/
dorofeev_denis
/
universal_shell_for_ORACLE
Обзор
Документация
Войти
/
dorofeev_denis
/
universal_shell_for_ORACLE
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
Thread_unit.pas
433 строки
20 KB
dorofeev_denis
upload files
18 фев 2026, 17:52
Верифицирован
18 фев 2026, 17:52
108b95f
Код
Авторство
О чём код?
{������ ��������� ��� ���������� � ����� � ����������� �������� � Excel} unit Thread_unit; interface uses Winapi.Windows, System.Classes, System.SysUtils, System.Variants, Vcl.Dialogs, Data.DB, Vcl.Graphics, Uni, OracleUniProvider, DBAccess, ComObj, ActiveX, System.UITypes, UNIT_TEXT_FILES_AND_FOLDERS, OraErrorUni; type Thread = class(TThread) UniConnection1: TUniConnection; UniQuery1: TUniQuery; procedure Export_to_Excel; procedure Main_work; procedure Cancel_script; private { Private declarations } num_of_rows: integer; // ���������� �������, ������������ ��������. � ������� ����� ������������ ����������� �������. //� ���������, �. ����� �����: "����� �������� �����-�� �������� � ���������, ������� ������ ���������� ������� Synchronize, ����� ������������ ����������� �������" num_of_fields: integer; // ���������� ��������, ������������ �������� protected procedure Execute; override; end; implementation uses Unit1; { Important: Methods and properties of objects in visual components can only be used in a method called using Synchronize, for example, Synchronize(UpdateCaption); and UpdateCaption could look like, procedure Thread.UpdateCaption; begin Form1.Caption := 'Updated in a thread'; end; or Synchronize( procedure begin Form1.Caption := 'Updated in thread via an anonymous method' end ) ); where an anonymous method is passed. Similarly, the developer can call the Queue method with similar parameters as above, instead passing another TThread class as the first parameter, putting the calling thread in a queue with the other thread. } { Thread } procedure Thread.Export_to_Excel; var i, j: integer; FData: Variant; FormatSettings : TFormatSettings; out_value: TDateTime; // ��� �������� ���������� �������������� �������� � ���� ��� �������� ������������� �������� � Excel i_progress_bar: integer; // ������� ������� ������� num_cycle, k, ostatok, next_line: integer; exl, Column, Sheet, Range: OLEVariant; // � ������, ���� ���������� ��������� ��������, �� ��� ������������� �� ����������� begin try if num_of_rows <> 0 then if num_of_rows <= 1048576 then // ����������� ����� ������� � ����� ��� ���������� *.xlsx begin exl:= CreateOleObject('Excel.Application'); exl.DisplayAlerts:= true; //��������� ������� �� �������� ���������� MS Excel. �� ��������� ������� ���� � �������� �� ���������� ��������� exl.EnableEvents:= false; //���������� ������� Excel ��� ��������� ������ ���������� exl.WorkBooks.Add(-4167); //�������� ����� � ����� ����������� exl.WorkBooks[1] �� ��������� //exl.SheetsInNewWorkbook:= 1; // N - ���������� ������ (integer) //exl.Workbooks.Add('C:\������.xls'); //�������� ����� Sheet:= exl.WorkBooks[1].WorkSheets[1]; if num_parameter = 2 then Sheet.Name:= MyArray[0].value + ' - ' + MyArray[1].value; //��������� ��� ���� ����� Column:= Sheet.Rows; Sheet.Columns.ColumnWidth:= 30; Column.Rows.Font.Size:= 10; Column.Rows.Font.Name:= 'Arial'; //��������� ��� ����� ����� Column.Rows[1].Font.Size:= 14; Column.Rows[1].Font.Bold:= true; //������ ����� ��� ������ ������ Column.Rows[1].Font.Italic:= true; //������ Column.Rows[1].Interior.Color:= clYellow; //������� ������ ����� ������ Sheet.Cells[1, 1]:= StringReplace(Form1.label_script_name.Caption,'.sql','',[rfReplaceAll, rfIgnoreCase]); //������������ ������ Column.Rows[2].Font.Bold:= True; //������ ����� ������������ �������� //��������� ������ � ������������� ��������, ������ ������ � MS Excel ���������� � 1 for j:= 1 to num_of_fields do Sheet.Cells[2, j]:= UniQuery1.Fields[j-1].FieldName; // ������� � Fields ���������� � ���� num_cycle:= num_of_rows div 10000; // ���������� ������ ������� �� �������� 1000 ������� � Excel ostatok:= num_of_rows - 10000*num_cycle; //������� �� ������� �� �������� � 1000. ������� ����������� ��������. //������� ���������� ������ FData:= VarArrayCreate([1,10000,1,num_of_fields],varVariant); // ����������� ������������ ������ ��������� ���������� ������� FormatSettings:= TFormatSettings.Create('ru-RU'); // ���������� ������ ���������� � ����������������� ����������� //��������� ������ ������� �� UniQuery1 �� 1000 ����� next_line:= 3; //�������������� ������ Excel, ���� ��������� ������ i_progress_bar:= 0; for k:= 1 to num_cycle do // � ��� ������, ���� ����� �������� num_cycle = 0, �� � ���� �� �����, ����� ��������� ������ ������� begin for i:= 1 to 10000 do begin for j:=1 to VarArrayHighBound(FData,2) do if TryStrToDate(UniQuery1.Fields[j-1].AsString, out_value, FormatSettings) = true then // TryStrToDateTime � ������ ���������� ���� � ������ ���������� ��� ����, � �� ������!!! if out_value >= StrToDateTime('01.01.1900') then // Excel �� �������� ���� ������ XX ���� FData[i,j]:= UniQuery1.Fields[j-1].AsDateTime else FData[i,j]:= UniQuery1.Fields[j-1].AsWideString else FData[i,j]:= UniQuery1.Fields[j-1].AsWideString; Synchronize( procedure begin Form1.ProgressBar1.Position:= round(i_progress_bar/num_of_rows*1000) end); UniQuery1.Next; i_progress_bar:= i_progress_bar + 1; if terminated then //� ������, ���� ������������ �������� ������ ������ � ������ �������� ������ � Excel begin exl.DisplayAlerts:= false; //��������� ������ Excel �� ���������� ��������� exl.EnableEvents:= false; exl.Quit; //��������� Excel � ��������� ��� �� ������ Windows exl:= Unassigned; //���������� ���������� Excel Column:= Unassigned; Sheet:= Unassigned; Range:= Unassigned; Synchronize( procedure begin Form1.Button_execute.Enabled:= true; // �������������� ������ ������� ������� Form1.ButtonCancel.Visible:= false; Form1.ProgressBar1.Visible:= false; Form1.ProgressBar1.Position:= 0; Form1.StatusBar1.SimpleText:= '' end); exit; // ������� �� ��������� � ������ ������ �������� � Excel (��� ����� Exit �� �����������) end; end; //�������� �������� ��� ������� ������ Range:= Sheet.Range[Sheet.Cells[next_line,1],Sheet.Cells[next_line+9999,VarArrayHighBound(FData,2)]]; // +1 - ��-�� ������ ������������ �������� �������� ��������� �� 1 ������ ���� Range.Value:= FData; next_line:= 10000*k + 3; //����� ������� ������, � ������� ��������� ��������� ������ ����� //last_line:= next_line+999 end; for i:= 1 to ostatok do begin for j:=1 to VarArrayHighBound(FData,2) do if TryStrToDate(UniQuery1.Fields[j-1].AsString, out_value, FormatSettings) = true then if out_value >= StrToDateTime('01.01.1900') then // Excel �� �������� ���� ������ XX ���� FData[i,j]:= UniQuery1.Fields[j-1].AsDateTime else FData[i,j]:= UniQuery1.Fields[j-1].AsWideString else FData[i,j]:= UniQuery1.Fields[j-1].AsWideString; Synchronize( procedure begin Form1.ProgressBar1.Position:= round(i_progress_bar/num_of_rows*1000) end); UniQuery1.Next; i_progress_bar:= i_progress_bar + 1; if terminated then // � ������, ���� ������������ �������� ������ ������ � ������ �������� ������ � Excel begin exl.DisplayAlerts:= false; // ��������� ������ Excel �� ���������� ��������� exl.EnableEvents:= false; exl.Quit; // ��������� Excel � ��������� ��� �� ������ Windows exl:= Unassigned; // ���������� ���������� Excel Column:= Unassigned; Sheet:= Unassigned; Range:= Unassigned; Synchronize( procedure begin Form1.Button_execute.Enabled:= true; // �������������� ������ ������� ������� Form1.ButtonCancel.Visible:= false; Form1.ProgressBar1.Visible:= false; Form1.ProgressBar1.Position:= 0; Form1.StatusBar1.SimpleText:= '' end); exit; // ������� �� ��������� � ������ ������ �������� � Excel (��� ����� Exit �� �����������) end; end; Range:= Sheet.Range[Sheet.Cells[next_line,1],Sheet.Cells[next_line+ostatok-1,VarArrayHighBound(FData,2)]]; // +1 - ��-�� ������ ������������ �������� �������� ��������� �� 1 ������ ���� Range.Value:= FData; //Raise Exception.Create('������'); ��� ������� ���� � ������ ��������� ������ exl.EnableEvents:= true; //��������� ������� Excel exl.Visible:= true; //���������� Excel end else Synchronize( procedure begin //Memo_log('C������� �� ������� �����������!', empty_string); Form1.StatusBar1.SimpleText:= '���������� ������������ ������� �� ������� ��������� 1 048 576! ���������� ����������� �������� �� ������� ������!'; // MessageDlg('���������� ������������ ������� �� ������� ��������� 1 048 576! ���������� ����������� �������� �� ������� ������!', mtInformation, [mbOk], 0); end) else Synchronize( procedure begin //Memo_log('C������� �� ������� �����������!', empty_string); Form1.StatusBar1.SimpleText:= 'C������� �� ������� �����������!'; // MessageDlg('C������� �� ������� �����������!', mtInformation, [mbOk], 0); end); //����� ���������� ������� ������ ��������� ������� �������� � Excel, ������ ������, ���������� ������ ���������� ������� Synchronize( procedure begin Form1.StatusBar1.SimpleText:= '������ ��������� ���������!'; // //Form1.BringToFront; // ������ ���, ����� ���� ��������� ����� ������ �������� � Excel ���������� ������ ���� ���� �������� ����� Form1.Button_execute.Enabled:= true; Form1.ProgressBar1.Visible:= false; Form1.ButtonCancel.Visible:= false; end); {����������� ���������� ������ (�����������, ����� ����� �������� MS Excel ������� � ���������� ����� ��������). � ����� ������ ����� �������� ��������� �����, ����� Excel �� �������� ���� ������ => � ����� ������� �� ������ ����������� ���������� � ���������, �.�. ������� �����-��������� �� ������ � ������, �� ������ � ������ ��� ������} //exl:= Unassigned; // ���������� ���������� Excel //Column:= Unassigned; //Sheet:= Unassigned; //Range:= Unassigned; except on E:Exception do // � ������ ������������� ����� ������ � �������� ��������� ������� � �������� � Excel begin exl.Visible:= false; // �������� Excel ��� ��� �������� exl.EnableEvents:= false; exl.DisplayAlerts:= false; exl.Quit; //��������� Excel � ��������� ��� �� ������ Windows exl:= Unassigned; // ����������� ���������� Excel Column:= Unassigned; Sheet:= Unassigned; Range:= Unassigned; Synchronize( procedure begin Form1.Button_execute.Enabled:= true; // �������������� ������ ������� ������� Form1.ButtonCancel.Visible:= false; Form1.ProgressBar1.Visible:= false; Form1.ProgressBar1.Position:= 0; Form1.StatusBar1.SimpleText:= '������ ��� �������� ������ � MS Excel! �������� ������: ' + e.Message end); end; end; end; //��������� ������� ���� � ����� �����, � ������� ����� ��������� ������ function GetErrorsFileName(InputStr: TDateTime): string; var s: string; begin s:= DateTimeToStr(InputStr); s:= StringReplace(s, '.', '_', [rfReplaceAll, rfIgnoreCase]); s:= StringReplace(s, ' ', '_', [rfReplaceAll, rfIgnoreCase]); result:= StringReplace(s, ':', '_', [rfReplaceAll, rfIgnoreCase]) + '.log'; end; {��������� ������, ������� �� ������ � ���� try except end, ��� ���������� ��������� ���� ������ � ���������� procedure Thread.HandleException(Sender: TObject; E: Exception); begin Memo1.Clear; if E is EOraError then if (E as EOraError).ErrorCode = 1013 then //1013 - ������, ������������ ��� ��������� ���������� ������� begin Date_and_Time; Memo1.Lines.Add(p_time+' - ���������� SQL ������� �����������!') end else begin Date_and_Time; Memo1.Lines.Add(p_time+' - �������������� ������ ORACLE: '+e.Message); end end; } // �������� �� ������� ������ ������ ������� procedure Thread.Cancel_script; begin {���� ������ ��� �����������. �����������, � ����� ������ ������ ������� ���������� ������� ������� �� 2 �����: ���������� ���������� ������� � ������������ ���������� � ���� ������ �����. ������ ����������� �����������, ������� ����������� ������� AfterFetch �� ���������. � ��� ������������ ����� �� �������� ������������ ����� � ����������� � ������� �� ������������� �������. ������������� ���������� ���������� Fetched ��� Fetching (�������� Fetching ��������������� ������ ��� ������ ������� ������, � �������� Fetched - ������ ����� ���������� ��� ������ ������� ������)} if UniQuery1.Fetched = false then UniQuery1.BreakExec; // ��� ������ ���������� �������. � ������, ���� ������ ��� ��������, �� ������ ����� �� ���������� ������ ORA, � ��������� UniQuery1.active = false, ������� ����� ������ ����� ������ �������� ������������� ������ � ���, ��� DataSet is closed end; procedure Thread.Main_work; begin try CoInitialize(nil); // ��� ������������� �������� COM, � ����� ������ - ��� ������ � Excel. UniConnection1 � UniQuery1 ���� ���������� COM, �� ����� � ���������� ��� ����������� � ����� ������� try UniQuery1.Connection:= UniConnection1; // ��������� ����� ����������� � ����� ������������� ������� UniConnection1.Connected:= true; //��������� ����������� � ������� except on E:Exception do // � ������ ������ ����������� � �� begin //Memo_log('������ ���������� � �������� �� ' + Form1.UniConnection1.Server + ': ' + e.message, empty_string); UniConnection1.Connected:= false; // ��� ������������� ������ ������� ������� ����������� �� ������� FreeAndNil(UniConnection1); // ����� ����������� ���������� � ������ FreeAndNil(UniQuery1); Create_Text_File(Errors, path_exe + '\LOG\' + 'Errors_' + GetErrorsFileName(now)); //�������� ����� ���� ������ Write_Text_File(Errors, path_exe + '\LOG\' + 'Errors_' + GetErrorsFileName(now), '������ ���������� � �������� �� ' + UniConnection1.Server + ': ' + e.message); // ������ � ���� ���� ������ Synchronize( procedure begin Form1.Button_execute.Enabled:= true; //��� ������ ���������� � �������� ����� ������� ������ ���������� ������� ���������� Form1.StatusBar1.SimpleText:= '������ ���������� � �������� ��!!! ' + e.message; MessageDlg('������ ���������� � �������� ��!!! ' + e.message, mtInformation, [mbOk], 0); end ); Exit //���� �� ��������� ������ ��������, � ���������� ��� �� ��������� end; end; try {�������� �������� ���� ������} Create_Directory(path_exe, '\LOG'); // ����� �������� ������� ������ ����������� ������ ���������� ������� � ���������� ������ ������ Synchronize( procedure begin Form1.Button_execute.Enabled:= false; Form1.ButtonCancel.Visible:= true; Form1.ProgressBar1.Position:= 0 //����� �������� �������� �������� end); {****���� ���������� ������� � �� � �������� ������ � EXCEL********************} //Form1.UniQuery1.FetchingAll; //���������� ��� ������ //Form1.UniQuery1.Options.QueryRecCount:= true; //����������� �������� ��� ����������� ���������� ������� //Form1.UniQuery1.SpecificOptions.Values['Oracle.NonBlocking']:= 'true'; //Form1.UniQuery1.Open; //Form1.UniQuery1.Params.Items[0].AsString .ParamByName('date_start').ParamType:= ptInput; //Form1.UniQuery1.ParamByName('date_start').AsString:= DateToStr(Form1.DateTimePicker1.Date); UniQuery1.SpecificOptions.Values['FetchAll']:= 'true'; //���������� ��� ������ �� ������� UniQuery1.Execute; Synchronize( procedure begin Form1.StatusBar1.SimpleText:= '������ ������� ��������, ������ �������� �������� � MS Excel, ��������...'; Form1.ProgressBar1.Visible:= true; //���������� ������ �������� � MS Excel end); num_of_rows:= UniQuery1.RecordCount; //����� �����, ������������ �������� num_of_fields:= UniQuery1.FieldCount; //����� ��������, ������������ �������� Export_to_Excel; // �������� ������ � Excel {*****����� ����� ���������� ������� � �� � �������� � EXCEL***************************************************************} except on E:Exception do // � ������ ������������� ����� ������ � �������� ��������� ������� � �������� � Excel begin Synchronize( procedure begin Form1.Button_execute.Enabled:= true; // �������������� ������ ������� ������� Form1.ButtonCancel.Visible:= false; Form1.ProgressBar1.Visible:=false; Form1.ProgressBar1.Position:= 0; end); if not (E is EDAError) then // � ������ ������������� ������ ������, �� ��������� � ���������� ������� �� ������� �� begin Synchronize( procedure begin Form1.StatusBar1.SimpleText:= '������ ���� ������! �������� ������: ' + e.Message; MessageDlg('������ ��� ��������� �������! ��������� � ������������ �������� ���������� ��� ���������� � ������������! �������� ������: ' + e.Message, mtInformation,[mbOk],0); end); // ������ ������ � ��� Create_Text_File(Errors, path_exe + '\LOG\' + 'Errors_' + GetErrorsFileName(now)); //�������� ����� ���� ������ Write_Text_File(Errors, path_exe + '\LOG\' + 'Errors_' + GetErrorsFileName(now), '������ �������� ������ �� ��, ���������� � ������������! �������� ������: ' + e.message); end else // ������ ������� � ���������� ������� �� ������� ������� �� if (E as EDAError).ErrorCode = 1013 then // ORA-01013 ������������� ��������� ������ ������� ��������, �.�. ������������ ����� �� ������ ������ begin Synchronize( procedure begin Form1.StatusBar1.SimpleText:= '���������� ������� ��������!' end); end else begin Synchronize( procedure begin Form1.StatusBar1.SimpleText:= '������ ���� ������! �������� ������: ' + e.Message; MessageDlg('������ ��� ��������� �������! ��������� � ������������ �������� ���������� ��� ���������� � ������������! �������� ������: ' + e.Message, mtInformation,[mbOk],0); end); // ������ ������ � ��� Create_Text_File(Errors, path_exe + '\LOG\' + 'Errors_' + GetErrorsFileName(now)); //�������� ����� ���� ������ Write_Text_File(Errors, path_exe + '\LOG\' + 'Errors_' + GetErrorsFileName(now), '������ �������� ������ �� ��, ���������� � ������������! �������� ������: ' + e.message); end end end finally // ���� ����������� ������ UniConnection1.Connected:= false; // ��������� ����������� �� ������� ����� ��������� ������ � ����� ������ FreeAndNil(UniConnection1); // ����� ����������� ���������� � ������ FreeAndNil(UniQuery1); CoUninitialize; // ���������� ������ � COM end end; // �������� ���������, � ������� ����������� ����� procedure Thread.Execute; begin { Place thread code here } Main_work; end; end.