Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2006.04.30;
Скачать: [xml.tar.bz2];

Вниз

Пожалуйста, помогите организовать цикл!   Найти похожие ветки 

 
Pretender ©   (2006-04-11 11:51) [0]

Доброго времнени суток всем! Я хочу написать программу, которая формировала бы письма с вложениями и ложила их в активный ящик. Количество файлов задается вручную, из формы. У меня возникла проблема с формированием цикла. Вот часть кода:

procedure TForm1.Button1Click(Sender: TObject);
var i,n: integer;
   F1: TextFile;
   St1: String;
begin
n:=StrToInt(Edit1.Text);
  AssignFile(F1,"sm.ini");
 Reset(F1);
 Readln(F1,st1);
for i:=n downto 1 do

 IdMessage1.Recipients.EMailAddresses:=st1;
 IdMessage1.CharSet:="Windows-1251";
 IdMessage1.ContentType:="text/plain";
 idMessage1.Subject:="Пополение (часть " + IntTostr(i) + " из " + IntTostr(n) + ")" ;
        for i:=n downto 1 do Memo1.Lines.Insert(0,"Сформирован файл пополения № " + IntTostr(i));

end;

Вот как сделать, чтобы последовательно формировалось сообщение от 1 до n (n вводится вручную). Т.е. сначала создается объкт - само сообщение, затем последовательно заполняется адрес (из ini-файла), тема (тоже генерируется соответствующие цифры в теме), присоединяется файл и письмо ложится в активный ящик (не отправляется, просто ложится), а затем формируется новое сообщение т.д. до n. Как это реализовать? Я уже совсем запутался... :(


 
tsa   (2006-04-11 11:52) [1]

Спамеры обнаглели!


 
Вот так   (2006-04-11 12:08) [2]

for i:=n downto 1 do begin

IdMessage1.Recipients.EMailAddresses:=st1;
IdMessage1.CharSet:="Windows-1251";
IdMessage1.ContentType:="text/plain";
idMessage1.Subject:="Пополение (часть " + IntTostr(i) + " из " + IntTostr(n) + ")" ;
       for i:=n downto 1 do Memo1.Lines.Insert(0,"Сформирован файл пополения № " + IntTostr(i));
end;


 
tsa   (2006-04-11 12:10) [3]


>  [2] Вот так   (11.04.06 12:08)

А ещё можно поливать пивом из пульверизатора тополя


 
Pretender ©   (2006-04-11 13:13) [4]


> Спамеры обнаглели!

Уважемый, я с Вами не знаком, поэтому скажу просто: не гоните! Я симтемный администратор и эта программа не для организации массовых рассылок, а для отправки пополнения нашим клиентам.


> for i:=n downto 1 do begin
>
> IdMessage1.Recipients.EMailAddresses:=st1;
> IdMessage1.CharSet:="Windows-1251";
> IdMessage1.ContentType:="text/plain";
> idMessage1.Subject:="Пополение (часть " + IntTostr(i) +
> " из " + IntTostr(n) + ")" ;
>        for i:=n downto 1 do Memo1.Lines.Insert(0,"Сформирован
> файл пополения № " + IntTostr(i));
> end;

Вот спасибо, на работу приду - попробую.


 
Pretender ©   (2006-04-11 14:22) [5]

Гм. Это поборол... А в ящик активный не кладётся... Куда посмотреть?


 
Anatoly Podgoretsky ©   (2006-04-11 14:37) [6]

Пригласите программиста, а не системного администратора.


 
Pretender ©   (2006-04-11 14:39) [7]

Да я сам разобраться хочу...


 
Anatoly Podgoretsky ©   (2006-04-11 14:46) [8]

Это долго


 
Сергей М. ©   (2006-04-11 14:48) [9]


> в ящик активный не кладётся


Что есть "активный ящик" и где в своем коде ты в него пытаешься что-то "накласть" ?


 
Pretender ©   (2006-04-11 14:54) [10]

Активный ящик - у меня TheBat висит в трее, в нем ящик с каталогом "Исходящие", в этот каталог письмо и должно попасть.


 
Сергей М. ©   (2006-04-11 15:01) [11]


> Pretender ©   (11.04.06 14:54) [10]


Не в ту сторону копаешь.

IdSMTP знать не знает ни про какие TheBat и знать не обязан.


 
Pretender ©   (2006-04-11 15:07) [12]

А каким образом сформированное сообщение попадёт в каталог "Исходящие"? Вот, допустим, консольная версия архиватора rar при задании сооответствующего параметра в командной строке, архивированные файлы пихает прямо в "Исходящие". Как это можно реализовать?
А в коде естественно ничего нет, я пока не знаю как это делать :)


 
Сергей М. ©   (2006-04-11 15:26) [13]


> А каким образом сформированное сообщение попадёт в каталог
> "Исходящие"?
> консольная версия архиватора rar при задании сооответствующего параметра в > командной строке, архивированные файлы пихает прямо в "Исходящие"


Средствами MapiSendMail().

Это ф-ция фигурирует в составе MS MAPI, к коему IdSMTP не имеет ни малейшего отношения - компонент этот работает с SMTP-сервисом напрямую, минуя любой из прочих SMTP-клиентов, установленных в системе.

Говорят же тебе - найми программиста, не парься)


 
Pretender ©   (2006-04-11 16:07) [14]


> найми программиста

Не, я не работодатель, чтоб людей нанимать, это так, чисто для себя. Что ж, спасибо за помосщь, буду сам разбираться.


 
tsa   (2006-04-11 16:16) [15]

Это не правильный системный администратор.


 
Pretender ©   (2006-04-12 12:46) [16]

rocedure TForm1.Button1Click(Sender: TObject);

var i,n,k: integer;
   F: TextFile;
   St1,St2: String;
   mail: TStringList;
begin
 ShellExecute(Application.MainForm.Handle,nil,Pchar("rar.exe"),"e -y *.rar",nil,SW_ShowNormal);
 if StrToInt(Edit1.Text)>1 then
 ShellExecute(Application.MainForm.Handle,nil,Pchar("rar.exe"),"m -y -m5 -v1000 -ag0M0A popoln *.ans",nil,SW_ShowNormal) else
 ShellExecute(Application.MainForm.Handle,nil,Pchar("rar.exe"),"m -y -m5 -ag0M0A popoln *.ans",nil,SW_ShowNormal);
 n:=StrToInt(Edit1.Text);
 AssignFile(F,"sm.ini");
 Reset(F);
 Readln(F,st1);
 Readln(F,st2);

 for i:=1 to n do begin
   mail := TStringList.Create;
 try
   mail.values["to"] := st1;

   mail.values["subject"] := "Пополнение (часть " + IntTostr(i) + " из " + IntTostr(n) + ")";
   mail.values["body"] := "Test";
   mail.values["attachment0"] := st2 + "\Test.txt";
   sendEMail(Application.Handle, mail);

 finally

   mail.Free;

   for k:=n downto 1 do Memo1.Lines.Insert(0,"Сформировано письмо № " + IntTostr(k));

 end;

  CloseFile(F);
end;

Теперь проблема в том, что первый раз параметры st1 и st2 берутся из файла нормамально, а если (не закрывая проекта) нажать ещё раз кнопку Button1, то приложение вылетает с эксепшеном "Project Project1.exe raised exception class EInOutError with message "I/O error 103"" на строчке CloseFile(F). Как это корректно реализовать?


 
Старик   (2006-04-12 12:57) [17]

Ну... рассылку клиентам организовать... тут два варианта:
1. Твоя прога сама напрямую на мыло высылает сформированные письма. Это, имхо, лучший вариант. Пример на отслыку почты есть в демках делфи.
2. С другой стороны, если тебе нужно, чтобы твои сформированные письма появлялись именно в Бате и именно в его ящике... я вижу только один способ - редактировать соответствующий файл у Бата - он свои почтовые архивы хранит у себя в директории. Вот один из тех файликов и надо редактировать. А потом не забыть перегрузить Бата.


 
Pretender ©   (2006-04-12 14:02) [18]

Старик

Да я практически всё сделал, только непонятно, почему при первом нажатии инишка читается, а при втором и т.д. уже нет - вот в чём вопрос.


 
Anatoly Podgoretsky ©   (2006-04-12 14:10) [19]

Pretender ©   (12.04.06 14:02) [18]
С инишками так не работают
AssignFile(F1,"sm.ini");
Reset(F1);


 
Pretender ©   (2006-04-12 14:34) [20]

Anatoly Podgoretsky

Делал я так, тоже самое. Верней эксепшн возникает на CloseFile(F1), если CloseFile(F1) не ставить, письма второй раз не генерятся.


 
Kolan ©   (2006-04-12 14:35) [21]

С инишками так не работают
AssignFile(F1,"sm.ini");
Reset(F1);


Есть класс TIniFile...


 
Pretender ©   (2006-04-12 15:34) [22]

Вот что я сделал:

В процедуре Button1Click добавил

var Cfg: TIniFile;

begin

 Cfg:=TIniFile.Create("sm.ini");
 st1:=Cfg.ReadString("Config","Addr","");
 st2:=Cfg.ReadString("Config","Path","");
.....

Инишка выглядит так
[Config]
Addr=user@xyz.com
Path=C:\1

Так вот, эти значения в переменные st1, st2 не заносятся... А почему?


 
Pretender ©   (2006-04-13 08:24) [23]

Всё просто оказалось, нужно вписать ExtractFilePath(Application.Exename) и всё работает. Да... господа профи, хорошо же вы новичкам помогаете, ничего не скажешь. :)


 
balepa ©   (2006-04-13 08:26) [24]

Да, они такие


 
Pretender ©   (2006-04-13 09:58) [25]

Нет, без обид только. Просто я сравниваю как сисадмины помогают начинающим - если вопрос задан по существу, тебе на него ответят. А тут почему-то нет. Хотя... С сабжем помогли, а всё остальное - это уже другая песня :)


 
Anatoly Podgoretsky ©   (2006-04-13 10:37) [26]

Pretender ©   (13.04.06 09:58) [25]
Программисты такие же, если вопрос задан по существу, тебе на него ответят.


 
Pretender ©   (2006-04-13 11:51) [27]

Ок. Тогда вопрос по существу :):

как с помощью FindFirst, FindNext и FindClose организовать поиск архивов по маске popoln*.part*.rar и по завершении поиска занести их количество в переменную n?


 
Anatoly Podgoretsky ©   (2006-04-13 11:58) [28]

Pretender ©   (13.04.06 11:51) [27]
Это есть в справке


 
Pretender ©   (2006-04-13 12:57) [29]

Вот что я сделал пока:

 if FindFirst(st2, faArchive, SR) = 0 then
    n := 0;
    begin
       repeat
       if (sr.Attr and faArchive) = sr.Attr then
       begin
       n := n + 1;
       label3.Caption:= sr.Name;
       end;
       until FindNext(SR) <> 0;
     FindClose(SR);
    end;

Но почему-то в label3.Caption имя файла не заносится...


 
Anatoly Podgoretsky ©   (2006-04-13 13:04) [30]

Точку останова поставь.
Код не понятный, что ты хочешь сделать?


 
Плохиш ©   (2006-04-13 13:11) [31]


> Pretender ©   (13.04.06 12:57) [29]

if (sr.Attr and faArchive) = faArchive then


 
Anatoly Podgoretsky ©   (2006-04-13 13:23) [32]

Плохиш ©   (13.04.06 13:11) [31]
Но это же противоположный результат, чем в коде


 
Плохиш ©   (2006-04-13 13:26) [33]


> Anatoly Podgoretsky ©   (13.04.06 13:23) [32]

А я телепатор из ремонта в n-й раз получил, проверяю ;-)


 
Pretender ©   (2006-04-13 13:32) [34]


> А я телепатор из ремонта в n-й раз получил, проверяю

:)))

Anatoly Podgoretsky

Пытаюсь найти архивный файл и при нахождении оного прибавить n на единицу, а в Label3 занести имя файла (хоть какого-нибудь, наверно это будет последний файл) - если я правильно понял пример. Что значит точка останова - брейкпойнт? Дело в том, что и в справке и в книге, в которой я смотрю пример использования, примеры сделаны ацтойно (не исключаю и свою глупую голову)...


 
Pretender ©   (2006-04-13 14:09) [35]

Да, st2 содержит путь к папке, в которой эти архивы лежат (берется из ини файла).


 
Anatoly Podgoretsky ©   (2006-04-13 14:21) [36]

Pretender ©   (13.04.06 13:32) [34]
1. Тогда согласно телепатору от Плохиша.
2. N := N + 1
3. Label3.Caption := sr.Name;
4. это в отладчике, нажимаешь F5 программа остановится в этой точке
5. примеры сделаны нормально, но если не устраивают, то ко мне на сайт, там самая правильная версия по данному вопросу.


 
Pretender ©   (2006-04-13 14:42) [37]

Это DirScan или File Size Analyzer? П. 2-3 к чему? Сделал

if (sr.Attr and faArchive) = faArchive then

в n занеслось 1, в labelCaption занеслось пустое место, т.е. ничего.


 
Anatoly Podgoretsky ©   (2006-04-13 14:54) [38]

Ни то ни другое, это программы -  очень старые не оптимальные, на сайте есть FAQ из ФИДО, вот его смотреть, при том найдешь ответы и на другие вопросы. Кроме это могут быть полезны две статьи
1. Двоичная математика, работа с битовой логикой
2. Работа с файлами Паскаля


Пункт 2 и 3 к тому, что ты про них спросил.


 
Плохиш ©   (2006-04-13 15:00) [39]


> в n занеслось 1, в labelCaption занеслось пустое место,
> т.е. ничего.

Даю 98%, что туда занеслась точка.


 
Pretender ©   (2006-04-13 15:13) [40]


> Даю 98%, что туда занеслась точка.

Нет, просто пустое место.

Anatoly Podgoretsky

Пошёл искать.


 
Pretender ©   (2006-04-13 16:06) [41]

Anatoly Podgoretsky
Объясните пожалуйста, как это работает:

procedure ScanDir(StartDir: string; Mask:string; List:TStrings);
var
 SearchRec : TSearchRec;
begin
 if Mask = "" then Mask := "popoln*.part*.r*"; //ну это параметр маски файла
 if StartDir[Length(StartDir)] <> "\" then StartDir := StartDir + "\"; // это        
даёт корневой каталог, хотя я не понял что даёт StartDir[число]

 if FindFirst(StartDir+Mask, faAnyFile, SearchRec) = 0 then //если нет
                                                  найденных файлов, то запустить поиск ?
 begin
   repeat
     Application.ProcessMessages;    
     if (SearchRec.Attr and faDirectory) <> faDirectory then // ?
       List.Add(StartDir + SearchRec.Name)
     else if (SearchRec.Name <> "..") and (SearchRec.Name <> ".") then begin
       List.Add(StartDir + SearchRec.Name + "\"); //почему тут \
       ScanDir(StartDir + SearchRec.Name + "\",Mask,List); //тут опять эта функция вызывается?
     end;
   until FindNext(SearchRec) <> 0;
   FindClose(SearchRec);
 end;

Вообщем, как это работает?
end;


 
Anatoly Podgoretsky ©   (2006-04-13 16:16) [42]

Это может работать, а может не работать, а в FAQ есть стопроцентно рабочий вариант от Юрия Зотова.


 
Pretender ©   (2006-04-13 16:22) [43]


> Anatoly Podgoretsky

Да оно-то работает! :) Как раз от Ю.Зотова. Только я не понимаю принцип, вот и всё. Поэтому прошу объяснить. если не трудно.


 
Pretender ©   (2006-04-13 16:25) [44]

Ой. Не Зотова, а Леонида Трояновского.


 
Anatoly Podgoretsky ©   (2006-04-13 16:37) [45]

Используй Зотова


 
Pretender ©   (2006-04-13 16:42) [46]

Пардон, почему? Работает же. В том виде, в котором я привёл. Я потом делаю n:=ListBox1.Items.Count; и, соответственно, по количеству итемов генерирую соответствующее количество писем. Я просто прошу объяснить как это работает (оно работает, но хочется до конца разобраться).


 
Anatoly Podgoretsky ©   (2006-04-13 16:50) [47]

Работает, но не во всех случаях.
А объяснять что, там все понятно, а что тебе не понятно ты не говоришь.
Вернись к предметному разговору и тебе расскажут.


 
Pretender ©   (2006-04-13 18:49) [48]

Что не понятно я в комментах написал со знаком "?". А на сайте Вашем действительно много полезной информации, потавлю ночью кое-что на закачку.


 
Anatoly Podgoretsky ©   (2006-04-13 22:13) [49]

Это рекурсивный поиск. Рекурсия это такая штука, когда из себя вызываешь себя.


 
Pretender ©   (2006-04-14 10:26) [50]

Странно, выявилась еще одна проблема: при первом нажатии на кнопку архив пакуется частями (свойство CheckBox1.Checked=True), формируется необходимое количество писем; а если сделать CheckBox1.Checked=False (т.е. снять флажок - соответствует одному архиву) и нажать второй раз, то ничего не происходит - мелькает окно архиватора, а в n заносится значение 0. Тоже происходит при CheckBox1.Checked=True если удалить архивный файл(ы). В чём проблема?

procedure TForm1.Button1Click(Sender: TObject);

var i,n,k: integer;
   St1,St2: String;
   mail: TStringList;
   Cfg: TIniFile;
   //SR: TSearchRec;

begin
 Cfg:=TIniFile.Create(ExtractFilePath(Application.Exename) + "sm.ini");
 if RadioButton1.Checked=True then st1:=Cfg.ReadString("Config","Addr1","") else
 if RadioButton2.Checked=True then st1:=Cfg.ReadString("Config","Addr2","");
 st2:=Cfg.ReadString("Config","Path","");
 Cfg.Free;
 ShellExecute(Application.MainForm.Handle,nil,Pchar("rar.exe"),"e -y *.rar",nil,SW_ShowMaximized);
 Sleep(1000);
 if CheckBox1.Checked=True then
 ShellExecute(Application.MainForm.Handle,nil,Pchar("rar.exe"),"m -y -m5 -v1000 -ag0M0A popoln *.dbf",nil,SW_ShowMaximized);
 if CheckBox1.Checked=False then
 ShellExecute(Application.MainForm.Handle,nil,Pchar("rar.exe"),"m -y -m5 -ag0M0A popoln *.dbf",nil,SW_ShowMaximized);
 ListBox1.Items.Clear;
 if CheckBox1.Checked=True then ScanDir1(st2,"",ListBox1.Items)
 else
 ScanDir2(st2,"",ListBox1.Items);

 n:=ListBox1.Items.Count;
 label3.caption:=inttostr(n);

 for i:=1 to n do begin
   mail := TStringList.Create;
 try
   mail.values["to"] := st1;
   mail.values["subject"] := "Пополнение (часть " + IntTostr(i) + " из " + IntTostr(n) + ")";
   mail.values["body"] := "Test";
   mail.values["attachment0"] := st2 + "\test.txt";
   sendEMail(Application.Handle, mail);

 finally

   mail.Free;

   for k:=n downto 1 do Memo1.Lines.Insert(0,"Сформировано письмо № " + IntTostr(k));

 end;

end;


 
Жуков Олег   (2006-04-14 10:46) [51]

Ничего не понял, но ShellExecute+Sleep тут - потенциальный источник багов. Вместо них CreateProcess+WaitForSingleObject.


 
Pretender ©   (2006-04-14 11:19) [52]

Сделал CreateProcess(Pchar("rar.exe"),"e -y *.rar","");, а отладчик ругается Incompatible types: "String" and "PSecurityAttributes"? Это на какой параметр - на первые два?


 
Virgo_Style ©   (2006-04-14 13:35) [53]

Pretender ©   (14.04.06 11:19) [52]

Класс. 5 баллов. F1 читайте, если нету - пойдите и плюньте тому, у кого купили, если языка не знаете - учите.


 
Pretender ©   (2006-04-14 14:17) [54]

Вот что напсано по поводу этого по F1:

Delphi syntax:

procedure CreateProcess(const ExeName, Args: string; const RemoteHost: string = "");

Description

CreateProcess starts a process for debugging.

The ExeName parameter is the path to the executable file to run.

The Args parameter is the command line to pass to the executable. It can be an empty string if there are no arguments.

The RemoteHost parameter is the name of the host where the process should run. The empty string means to use the local host.

The process is created and initially stopped at the main module’s entry point. After the debugger notifier receives the ProcessCreated notification, your wizard can leave the process in its stopped state or run the process.

И всё. Про WaitForSingleObject вообще ничего нет.



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2006.04.30;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.61 MB
Время: 0.013 c
15-1144740684
Der Nechk@ssoff
2006-04-11 11:31
2006.04.30
Собсна-вирусы


2-1144999043
Рафик
2006-04-14 11:17
2006.04.30
Помогите c TWordApplication


6-1137084456
bloodman
2006-01-12 19:47
2006.04.30
Перечислить сет. интерфейсы, Как?


2-1144931377
Кир
2006-04-13 16:29
2006.04.30
Классическая такая задачка...


2-1145002346
KyRo
2006-04-14 12:12
2006.04.30
Проблемы с реестром





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский