unit U_MakeUpdateBlock; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, RzButton, ExtCtrls, RzPanel, Mask, RzEdit, RzBtnEdt, ActnList, ImgList, ComCtrls, ToolWin, cxStyles, cxCustomData, cxGraphics, cxFilter, cxData, cxDataStorage, cxEdit, cxClasses, cxControls, cxGridCustomView, cxGridCustomTableView, cxGridTableView, cxGridLevel, cxGrid, cxButtonEdit, cxDropDownEdit, U_BaseCommon, U_Common, U_BaseConstants, U_BaseUpdate, U_SCSLists, cxCheckBox, cxCurrencyEdit, cxColorComboBox, cxSpinEdit, cxMemo, cxTextEdit, RzRadChk, siComp, cxDBLookupComboBox, cxLookAndFeels, cxLookAndFeelPainters, cxNavigator; const // Base Type Name btnCableProject = 'cpc'; type TMakeUpdateBlockSettings = class(TComponent) private FDirName: string; published property DirName: string read FDirName write FDirName; end; TF_MakeUpdateBlock = class(TForm) RzPanel1: TRzPanel; pnOkCancel: TRzPanel; btClose: TRzBitBtn; RzGroupBox1: TRzGroupBox; dtFrom: TRzDateTimeEdit; Label1: TLabel; Label2: TLabel; Label3: TLabel; dtTo: TRzDateTimeEdit; Label4: TLabel; edVersion: TRzEdit; Label5: TLabel; beTargetDir: TRzButtonEdit; RzGroupBox2: TRzGroupBox; ToolBar1: TToolBar; ToolButton1: TToolButton; ToolButton2: TToolButton; ImageList1: TImageList; ActionList1: TActionList; Act_AddCurrNB: TAction; Act_AddNB: TAction; Act_DelNB: TAction; ToolButton3: TToolButton; GL_Bases: TcxGridLevel; Grid: TcxGrid; GT_Bases: TcxGridTableView; GT_BasesPath: TcxGridColumn; GT_BasesType: TcxGridColumn; GT_BasesCatalogName: TcxGridColumn; GT_BasesOutFile: TcxGridColumn; Timer_EditValueChanged: TTimer; RzGroupBox3: TRzGroupBox; RzPanel2: TRzPanel; btStart: TRzBitBtn; meProtocol: TMemo; Button1: TButton; RzGroupBox4: TRzGroupBox; cbIncludeVirtualCompons: TRzCheckBox; RzGroupBox5: TRzGroupBox; cbIncludeComponsWithProps: TRzCheckBox; cbOnlyVirtualCompons: TRzCheckBox; siLang1: TsiLang; RzGroupBox6: TRzGroupBox; cbGuideProperties: TRzCheckBox; cbAllowEditDate: TRzCheckBox; cbGuideUGO: TRzCheckBox; procedure pnOkCancelResize(Sender: TObject); procedure GT_BasesTypePropertiesValidate(Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); procedure Act_AddCurrNBExecute(Sender: TObject); procedure Act_AddNBExecute(Sender: TObject); procedure Act_DelNBExecute(Sender: TObject); procedure GT_BasesFocusedRecordChanged(Sender: TcxCustomGridTableView; APrevFocusedRecord, AFocusedRecord: TcxCustomGridRecord; ANewItemRecordFocusingChanged: Boolean); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure GT_BasesEditValueChanged(Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem); procedure Timer_EditValueChangedTimer(Sender: TObject); procedure btStartClick(Sender: TObject); procedure Button1Click(Sender: TObject); function GetSQLConditionByDates: String; private GForm: TForm; FBaseTypeCaptions: TStringList; FBaseTypeNames: TStringList; procedure SetControls; procedure AddBase(const ADBPath: String); procedure AddBaseType(const ACaption, AName: String); procedure AddToProtocol(const AMessage: String; AIndent: Integer); procedure AfterBaseTypeChanged(ARecordIndex, ATypeIndex: Integer); function CheckPathInGrid(const ADBPath: String; ARecordindexToSkip: Integer): Boolean; function CheckUniquValuesInColumn(AColumnIndex: Integer; AOutNoUniqueValue: PString): Boolean; public Constructor Create(AOwner: TComponent; AForm: TForm); Destructor Destroy; override; function Execute: Boolean; end; //var // Form1: TForm1; implementation Uses U_Main; {$R *.dfm} constructor TF_MakeUpdateBlock.Create(AOwner: TComponent; AForm: TForm); begin GForm := AForm; inherited Create(AOwner); end; destructor TF_MakeUpdateBlock.Destroy; begin inherited; end; procedure TF_MakeUpdateBlock.pnOkCancelResize(Sender: TObject); begin SetMiddleControlChilds(TControl(Sender), TControl(Self)); end; function TF_MakeUpdateBlock.Execute: Boolean; begin edVersion.Text := VersionEXE; beTargetDir.Text := GetPathToDevelopment; dtFrom.Date := Now; dtTo.Date := Now; SetControls; ShowModal; end; procedure TF_MakeUpdateBlock.SetControls; begin Act_DelNB.Enabled := GT_Bases.DataController.RecordCount > 0; end; procedure TF_MakeUpdateBlock.AddBase(const ADBPath: String); var RecIndex: Integer; begin if Not CheckPathInGrid(ADBPath, -1) then begin RecIndex := GT_Bases.DataController.AppendRecord; GT_Bases.DataController.Values[RecIndex, GT_BasesPath.Index] := ADBPath; GT_Bases.DataController.Values[RecIndex, GT_BasesType.Index] := TcxComboBoxProperties(GT_BasesType.Properties).Items[0]; AfterBaseTypeChanged(RecIndex, -1); SetControls; end; end; procedure TF_MakeUpdateBlock.AddBaseType(const ACaption, AName: String); begin FBaseTypeCaptions.Add(ACaption); FBaseTypeNames.Add(AName); TcxComboBoxProperties(GT_BasesType.Properties).Items.Add(ACaption); end; procedure TF_MakeUpdateBlock.AddToProtocol(const AMessage: String; AIndent: Integer); begin meProtocol.Lines.Add(DupStr(' ', AIndent) + AMessage); end; procedure TF_MakeUpdateBlock.AfterBaseTypeChanged(ARecordIndex, ATypeIndex: Integer); var TypeIndex: Integer; CatalogNameForCompons: string; begin TypeIndex := ATypeindex; if Typeindex = -1 then TypeIndex := FBaseTypeCaptions.IndexOf(GT_Bases.DataController.Values[ARecordIndex, GT_BasesType.Index]); if TypeIndex <> -1 then begin CatalogNameForCompons := 'Добавлено для версии'; if FBaseTypeNames[TypeIndex] = btnCableProject then CatalogNameForCompons := 'Added for version'; CatalogNameForCompons := CatalogNameForCompons +' '+ edVersion.Text; GT_Bases.DataController.Values[ARecordIndex, GT_BasesCatalogName.Index] := CatalogNameForCompons; GT_Bases.DataController.Values[ARecordIndex, GT_BasesOutFile.Index] := 'upd'+RemoveSymbolFromStr(edVersion.Text, '.')+'_'+FBaseTypeNames[TypeIndex]+'.'+enUpd; end; end; function TF_MakeUpdateBlock.CheckPathInGrid(const ADBPath: String; ARecordindexToSkip: Integer): Boolean; var i: Integer; DBPath: String; begin Result := false; if ADBPath <> '' then begin DBPath := AnsiUpperCaseFileName(ADBPath); for i := 0 to GT_Bases.DataController.RecordCount - 1 do begin if (ARecordindexToSkip = -1) or (ARecordindexToSkip <> i) then begin if AnsiUpperCaseFileName(GT_Bases.DataController.Values[i, GT_BasesPath.Index]) = DBPath then begin Result := true; MessageModal('НБ "'+ADBPath+'" уже есть в списке', ApplicationName, MB_OK or MB_ICONINFORMATION); end; end; end; end; end; function TF_MakeUpdateBlock.CheckUniquValuesInColumn(AColumnIndex: Integer; AOutNoUniqueValue: PString): Boolean; var ColumnValues: TStringList; i: integer; begin Result := false; if AOutNoUniqueValue <> nil then AOutNoUniqueValue^ := ''; if GT_Bases.DataController.RecordCount > 1 then begin ColumnValues := TStringList.Create; for i := 0 to GT_Bases.DataController.RecordCount - 1 do begin if ColumnValues.IndexOf(GT_Bases.DataController.Values[i, AColumnIndex]) <> -1 then begin Result := true; AOutNoUniqueValue^ := GT_Bases.DataController.Values[i, AColumnIndex]; Break; //// BREAK //// end else ColumnValues.Add(GT_Bases.DataController.Values[i, AColumnIndex]); end; ColumnValues.Free; end; end; procedure TF_MakeUpdateBlock.GT_BasesTypePropertiesValidate( Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean); var TypeIndex: Integer; begin //if CheckPathInGrid(DisplayValue, GT_Bases.DataController.FocusedRecordIndex) then //begin // DisplayValue := GT_Bases.DataController.Values[GT_Bases.DataController.FocusedRecordIndex, GT_BasesType.Index]; //end; TypeIndex := FBaseTypeCaptions.IndexOf(DisplayValue); if TypeIndex = -1 then DisplayValue := GT_Bases.DataController.Values[GT_Bases.DataController.FocusedRecordIndex, GT_BasesType.Index] else AfterBaseTypeChanged(GT_Bases.DataController.FocusedRecordIndex, TypeIndex); GT_Bases.DataController.Values[GT_Bases.DataController.FocusedRecordIndex, GT_BasesType.Index] := DisplayValue; end; procedure TF_MakeUpdateBlock.Act_AddCurrNBExecute(Sender: TObject); begin AddBase(TF_Main(GForm).GSCSBase.DBName); end; procedure TF_MakeUpdateBlock.Act_AddNBExecute(Sender: TObject); var OpenDialog: TOpenDialog; begin OpenDialog := TOpenDialog.Create(Self); try OpenDialog.Title := 'Добавление НБ...'; if OpenDialog.FileName = '' then OpenDialog.InitialDir := ExtractFileDir(Application.ExeName); OpenDialog.DefaultExt := '*.'+enDat; OpenDialog.Filter := GetDialogFilter(exdBase, enDat)+'|'+ GetDialogFilter(exdAll, '*'); OpenDialog.Options := OpenDialog.Options - [ofNoChangeDir] + [ofOverwritePrompt]; if OpenDialog.Execute then AddBase(OpenDialog.FileName); finally FreeandNil(OpenDialog); end; end; procedure TF_MakeUpdateBlock.Act_DelNBExecute(Sender: TObject); begin GT_Bases.DataController.DeleteFocused; SetControls; end; procedure TF_MakeUpdateBlock.GT_BasesFocusedRecordChanged( Sender: TcxCustomGridTableView; APrevFocusedRecord, AFocusedRecord: TcxCustomGridRecord; ANewItemRecordFocusingChanged: Boolean); begin // end; procedure TF_MakeUpdateBlock.FormCreate(Sender: TObject); begin FBaseTypeCaptions := TStringList.Create; FBaseTypeNames := TStringList.Create; GT_BasesPath.DataBinding.ValueTypeClass := TcxStringValueType; GT_BasesType.DataBinding.ValueTypeClass := TcxStringValueType; GT_BasesCatalogName.DataBinding.ValueTypeClass := TcxStringValueType; GT_BasesOutFile.DataBinding.ValueTypeClass := TcxStringValueType; AddBaseType('СКС', 'scs'); AddBaseType('Телеком', 'telecom'); AddBaseType('Трубы', 'tube'); AddBaseType('CableProject CAD', btnCableProject); AddBaseType('Panduit', 'panduit'); AddBaseType('rdm', 'rdm'); //TcxComboBoxProperties(GT_BasesType.Properties).Items.Add('СКС'); //TcxComboBoxProperties(GT_BasesType.Properties).Items.Add('Телеком'); //TcxComboBoxProperties(GT_BasesType.Properties).Items.Add('Трубы'); //TcxComboBoxProperties(GT_BasesType.Properties).Items.Add('CableProject CAD'); end; procedure TF_MakeUpdateBlock.FormDestroy(Sender: TObject); begin FreeAndNil(FBaseTypeCaptions); FreeAndNil(FBaseTypeNames); end; procedure TF_MakeUpdateBlock.GT_BasesEditValueChanged( Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem); begin //GT_Bases.OnEditValueChanged := nil; //Timer_EditValueChanged.Enabled := true; end; procedure TF_MakeUpdateBlock.Timer_EditValueChangedTimer(Sender: TObject); begin TTimer(Sender).Enabled := false; try if GT_Bases.DataController.IsEditing then begin GT_Bases.DataController.Post; Application.ProcessMessages; end; finally GT_Bases.OnEditValueChanged := GT_BasesEditValueChanged; end; end; procedure TF_MakeUpdateBlock.btStartClick(Sender: TObject); var msgErr: String; NoUniqueValue: string; CanStart: Boolean; SrcBase: TBase; TrgBase: TBase; i, j, k: Integer; MakeUpdateParams: TMakeUpdateParams; UpdateInfoItem: TUpdateInfoItem; UpdateInfoCatalog: TUpdateInfoItem; UpdateInfoCatalogRelation: TUpdateInfoItem; UpdateInfoComponBeEmptyAfter: TUpdateInfoItem; UpdateInfoCompPropRelAfter: TUpdateInfoItem; AdditionUpdateInfo: TUpdateInfo; AdditionUpdateInfoItem: TUpdateInfoItem; UpdateInfoProperty: TUpdateInfoItem; UpdateMaker: TBaseUpdateMaker; MakeUpdateResults: TUpdateBaseResults; SrcBasePath: String; TrgBasePath: String; NBEmtyPath: String; PathID: TIntList; TopCatalogIDs: TIntList; IDComponent: Integer; IDCatalog: Integer; IDTopCatalog: Integer; IDVirtualCompons: TIntList; IsVirtualCompon: Integer; FieldNames: TStringList; ItemIndex: Integer; ProcName: String; ProtocolIndent: Integer; ProtocolIndentStep: Integer; ActRowLimit: Integer; // Tolik 28/08/2019 //OldTick, CurrTick: Cardinal; OldTick, CurrTick: DWord; // procedure FillUpdateInfoFromIntList(ADestUpdateInfoItem: TUpdateInfoItem; ASrcIDList: TIntList); var i: Integer; IDFromList: Integer; begin SetSQLToFIBQuery(SrcBase.QSelect, GetSQLByParams(qtSelect, ADestUpdateInfoItem.TableName, fnID+' = :'+fnID, nil, fnGUID), false); for i := 0 to ASrcIDList.Count - 1 do begin IDFromList := ASrcIDList[i]; if GetValueIndexFromSortedIntList(IDFromList, ADestUpdateInfoItem.IDListToMakeUpdateSorted) = -1 then begin SrcBase.QSelect.Close; SrcBase.QSelect.Params[0].AsInteger := IDFromList; SrcBase.QSelect.ExecQuery; if SrcBase.QSelect.RecordCount > 0 then begin ADestUpdateInfoItem.IDListToMakeUpdate.Add(IDFromList); ADestUpdateInfoItem.IDListToMakeUpdateSorted.Add(IDFromList); ADestUpdateInfoItem.GUIDListToMakeUpdate.Add(SrcBase.QSelect.Fields[0].AsString); ADestUpdateInfoItem.GUIDListToMakeUpdateSorted.Add(SrcBase.QSelect.Fields[0].AsString); end; end; end; end; procedure SelectComponsByElement(const AElementTableName, AElementSprFieldName: string; ASprUpdateInfoItem, AElementUpdateInfoItemAfter: TUpdateInfoItem); var IDCompon: Integer; IDElement: Integer; GUIDElement: String; ElementSprFieldValue: Integer; SpravTablesIDs: TIntList; ComponsToBeEmptyID: TIntList; begin {SetSQLToFIBQuery(SrcBase.QSelect, 'select ID, GUID from component '+ 'where ID in '+ '(select ID_COMPONENT from '+AElementTableName+' where (date_in between '''+DateToStr(dtFrom.Date)+''' and '''+DateToStr(dtTo.Date)+'''))'); while Not SrcBase.QSelect.Eof do begin IDCompon := SrcBase.QSelect.Fields[0].AsInteger; if UpdateInfoItem.IDListToMakeUpdateSorted.IndexOf(IDCompon) = -1 then begin UpdateInfoItem.IDListToMakeUpdate.Add(IDCompon); UpdateInfoItem.IDListToMakeUpdateSorted.Add(IDCompon); UpdateInfoItem.GUIDListToMakeUpdate.Add(SrcBase.QSelect.Fields[1].AsString); UpdateInfoItem.GUIDListToMakeUpdateSorted.Add(SrcBase.QSelect.Fields[1].AsString); end; SrcBase.QSelect.Next; end;} SpravTablesIDs := TIntList.Create; ComponsToBeEmptyID := TIntList.Create; SetSQLToFIBQuery(SrcBase.QSelect, 'select ID, GUID, ID_COMPONENT, '+AElementSprFieldName+' from '+AElementTableName+' '+ ' where '+GetSQLConditionByDates); while Not SrcBase.QSelect.Eof do begin IDElement := SrcBase.QSelect.Fields[0].AsInteger; GUIDElement := SrcBase.QSelect.Fields[1].AsString; IDCompon := SrcBase.QSelect.Fields[2].AsInteger; ElementSprFieldValue := SrcBase.QSelect.Fields[3].AsInteger; // Если такой компонент не попал в блок обновления if GetValueIndexFromSortedIntList(IDCompon, UpdateInfoItem.IDListToMakeUpdateSorted) = -1 then begin if GetValueIndexFromSortedIntList(IDCompon, ComponsToBeEmptyID) = -1 then InsertValueToSortetIntList(IDCompon, ComponsToBeEmptyID); if GetValueIndexFromSortedIntList(ElementSprFieldValue, SpravTablesIDs) = -1 then InsertValueToSortetIntList(ElementSprFieldValue, SpravTablesIDs); if GetValueIndexFromSortedIntList(IDElement, AElementUpdateInfoItemAfter.IDListToMakeUpdateSorted) = -1 then begin AElementUpdateInfoItemAfter.IDListToMakeUpdate.Add(IDElement); AElementUpdateInfoItemAfter.IDListToMakeUpdateSorted.Add(IDElement); AElementUpdateInfoItemAfter.GUIDListToMakeUpdate.Add(GUIDElement); AElementUpdateInfoItemAfter.GUIDListToMakeUpdateSorted.Add(GUIDElement); end; end; SrcBase.QSelect.Next; end; FillUpdateInfoFromIntList(ASprUpdateInfoItem, SpravTablesIDs); FillUpdateInfoFromIntList(UpdateInfoComponBeEmptyAfter, ComponsToBeEmptyID); FreeAndNil(ComponsToBeEmptyID); FreeAndNil(SpravTablesIDs); end; procedure FillUpdateInfoFromGUIDList(AGUIDList: TStringList; const ATableName, AGenName: string); var TableUpdateInfoItem: TUpdateInfoItem; IDList: TIntList; NewID: Integer; i: Integer; begin TableUpdateInfoItem := AdditionUpdateInfo.GetItemByTableName(ATableName); if TableUpdateInfoItem = nil then begin TableUpdateInfoItem := TUpdateInfoItem.Create(nil); TableUpdateInfoItem.TableName := ATableName; TableUpdateInfoItem.GeneratorName := AGenName; AdditionUpdateInfo.Add(TableUpdateInfoItem); end; // из GUID листа получаем список ID IDList := TIntList.Create; for i := 0 to AGUIDList.Count - 1 do begin NewID := GetIntFromTableByGUID(ATableName, fnID, AGUIDList[i], SrcBase.QSelect); if NewID <> 0 then IDList.Add(NewID); end; if IDList.Count > 0 then FillUpdateInfoFromIntList(TableUpdateInfoItem, IDList); IDList.Free; end; procedure SetRecordByVersion; var GUIDListToAdd: TStringList; begin //Exit; ///// EXIT ///// GUIDListToAdd := TStringList.Create; case CurrentNBBuildID of 31: //10.07.2009 begin // Типы компонентов на обновление - нужно для вкидки новых свойств на типах GUIDListToAdd.Clear; GUIDListToAdd.Add('{133728E3-D381-4B88-882A-70D051475D4C}'); // Розетка GUIDListToAdd.Add('{DCB31978-3D85-4DB9-B9FC-8E0407B09A37}'); // Модуль GUIDListToAdd.Add('{5367FED3-D1B0-4AED-9BB7-DE15833A32B2}'); // Блок розеток GUIDListToAdd.Add('{ED263346-F61C-4A69-98F4-5094287F39EF}'); // Патч панель GUIDListToAdd.Add('{E0459A33-2325-4DFB-BAF8-8C5B8B1E0E58}'); // Рабочее место GUIDListToAdd.Add('{32AE6103-84CE-468E-B1A6-2A50B7D241BB}'); // Шкаф GUIDListToAdd.Add('{044278F2-155D-4A7E-8857-FDC5BC939EAD}'); // Коммутатор GUIDListToAdd.Add('{F5609186-49AE-4C1A-9DCC-AECF2043177B}'); // Маршрутизатор GUIDListToAdd.Add('{6C5D9FFE-8F99-49A0-BDB6-F59A778B9C03}'); // ВО кабель GUIDListToAdd.Add('{24ACC09C-B7EA-4F56-93A6-32394AF920C5}'); // Кабельный канал GUIDListToAdd.Add('{87125212-553D-47B0-A4B0-FC19FE3C8801}'); // Кабельный канал лоток GUIDListToAdd.Add('{80B7A366-98B3-4D3A-A115-C64A3498218E}'); // Кабельный канал труба GUIDListToAdd.Add('{DE9D24BE-1066-4E62-B92B-ED2ABF6FB2BF}'); // Элемент кабельного канала GUIDListToAdd.Add('{82FE2C3B-2B46-4B66-96C4-99F22448006A}'); // Элемент кабельного канала. Адаптер GUIDListToAdd.Add('{E7FC6A24-ECF8-4762-953A-54B90AA73F33}'); // Элемент кабельного канала. Ввод в стену GUIDListToAdd.Add('{46367268-D388-4F92-AE80-E47284F4F4BE}'); // Элемент кабельного канала. Заглушка GUIDListToAdd.Add('{A16F3593-6FBF-4803-8FE5-A62C424C7C6D}'); // Элемент кабельного канала. Крестовина GUIDListToAdd.Add('{533794A3-6E36-4ED0-A1DF-91F2819BDDA0}'); // Элемент кабельного канала. Соединитель GUIDListToAdd.Add('{331A46EF-2E45-4519-88E7-314659663EAB}'); // Элемент кабельного канала. Тройник GUIDListToAdd.Add('{9F3FE58A-6D26-4630-9776-838874196A52}'); // Элемент кабельного канала. Уголок FillUpdateInfoFromGUIDList(GUIDListToAdd, tnComponentTypes, gnComponentTypesID); // Интерфейсы на обновление - нужно чтобы пошли связи x-pin с жилой GUIDListToAdd.Clear; GUIDListToAdd.Add(guidTwistedPair); GUIDListToAdd.Add(guidTwistedPairFTP); GUIDListToAdd.Add(guidInterfCoaxial); GUIDListToAdd.Add(guidInterf1pin); GUIDListToAdd.Add(guidInterf2pin); GUIDListToAdd.Add(guidInterf3pin); GUIDListToAdd.Add(guidInterf4pin); GUIDListToAdd.Add(guidInterf6pin); GUIDListToAdd.Add(guidInterf8pin); GUIDListToAdd.Add(guidInterf10pin); GUIDListToAdd.Add(guidInterf14pin); GUIDListToAdd.Add(guidInterf16pin); FillUpdateInfoFromGUIDList(GUIDListToAdd, tnInterface, gnInterfaceID); end; end; FreeAndNil(GUIDListToAdd); end; procedure SetTableRecords(const aTable, AGenName: string); var GUIDListToAdd: TStringList; begin GUIDListToAdd := TStringList.Create; SetSQLToFIBQuery(SrcBase.QSelect, 'select ID, GUID from '+aTable+' '+ ' where (date_in between '''+DateToStr(dtFrom.Date)+''' and '''+DateToStr(dtTo.Date)+''')'); while Not SrcBase.QSelect.Eof do begin GUIDListToAdd.Add(SrcBase.QSelect.Fields[1].AsString); SrcBase.QSelect.Next; end; if GUIDListToAdd.Count > 0 then begin FillUpdateInfoFromGUIDList(GUIDListToAdd, aTable, AGenName); AddToProtocol('Найдено '+IntToStr(GUIDListToAdd.Count)+' записей в '+aTable, ProtocolIndent); end; FreeAndNil(GUIDListToAdd); end; procedure RemoveFromUpdateInfoItem(AUpdateInfoItem: TUpdateInfoItem; Index: Integer); begin AUpdateInfoItem.IDListToMakeUpdateSorted.Remove(UpdateInfoItem.IDListToMakeUpdate[Index]); AUpdateInfoItem.GUIDListToMakeUpdateSorted.Delete( AUpdateInfoItem.GUIDListToMakeUpdateSorted.IndexOf(AUpdateInfoItem.GUIDListToMakeUpdate[Index])); AUpdateInfoItem.IDListToMakeUpdate.Delete(Index); AUpdateInfoItem.GUIDListToMakeUpdate.Delete(Index); end; begin ProcName := 'TF_MakeUpdateBlock.btStartClick'; ProtocolIndent := 0; ProtocolIndentStep := 3; msgErr := ''; CanStart := true; if GT_Bases.DataController.RecordCount = 0 then msgErr := 'Нужно добавить хоть одну НБ' else if CheckUniquValuesInColumn(GT_BasesOutFile.Index, @NoUniqueValue) then begin msgErr := 'Файл на выходе "'+NoUniqueValue+'" должен указываться один раз'; end; if msgErr = '' then begin if CheckUniquValuesInColumn(GT_BasesType.Index, @NoUniqueValue) then if MessageModal('Тип базы "'+NoUniqueValue+'" указан бальше одного раза. Продолжить?', ApplicationName, MB_ICONQUESTION or MB_YESNO) = IDNO then CanStart := false; end else begin CanStart := false; MessageModal(msgErr, ApplicationName, MB_ICONINFORMATION or MB_OK); end; if CanStart then begin TF_Main(GForm).GSCSBase.SimpleClose(true); try SrcBase := TBase.Create(TF_Main(GForm).DM.ConnectParams); TrgBase := TBase.Create(TF_Main(GForm).DM.ConnectParams); try NBEmtyPath := GetPathToNBEmpty; meProtocol.Lines.Clear; BeginProgress('', GT_Bases.DataController.RecordCount * 4); try OldTick := GetTickCount; for i := 0 to GT_Bases.DataController.RecordCount - 1 do begin try SrcBasePath := GT_Bases.DataController.Values[i, GT_BasesPath.Index]; TrgBasePath := beTargetDir.Text + '\' + GT_Bases.DataController.Values[i, GT_BasesOutFile.Index]; ProtocolIndent := 0; AddToProtocol('Обработка базы '+SrcBasePath, ProtocolIndent); ProtocolIndent := ProtocolIndent + ProtocolIndentStep; SrcBase.Open(SrcBasePath); UpdateInfoItem := TUpdateInfoItem.Create(nil); UpdateInfoItem.TableName := tnComponent; UpdateInfoItem.GeneratorName := gnComponentID; MakeUpdateParams := TMakeUpdateParams.Create; MakeUpdateParams.DBType := dbtComponent; MakeUpdateParams.FUpdateInfoItems.Add(UpdateInfoItem); AdditionUpdateInfo := TUpdateInfo.Create(true); // Справочные свойства - попадут в список, если не будут пустыми UpdateInfoProperty := TUpdateInfoItem.Create(nil); UpdateInfoProperty.TableName := tnProperties; UpdateInfoProperty.GeneratorName := gnPropertiesID; AdditionUpdateInfo.Add(UpdateInfoProperty); // ID и GUID компонентов, кот-е будут добавлены после составления блока обновления UpdateInfoComponBeEmptyAfter := TUpdateInfoItem.Create(nil); UpdateInfoComponBeEmptyAfter.TableName := tnComponent; UpdateInfoComponBeEmptyAfter.GeneratorName := gnComponentID; // свойства компонентов, кот-е будут добавлены после составления блока обновления UpdateInfoCompPropRelAfter := TUpdateInfoItem.Create(nil); UpdateInfoCompPropRelAfter.TableName := tnCompPropRelation; UpdateInfoCompPropRelAfter.GeneratorName := gnCompPropRelationID; //31.10.2012 - Справочные данные if cbGuideProperties.Checked then SetTableRecords(tnProperties, gnPropertiesID); // Tolik 04/01/2017 -- УГОшки if cbGuideUGO.Checked then SetTableRecords(tnObjectIcons, gnObjectIconsID); // отбираем GUIDы компонентов в промежутке дат SetSQLToFIBQuery(SrcBase.QSelect, 'select ID, GUID from component '+ 'where (Not name is null) and ('+GetSQLConditionByDates+')'); while Not SrcBase.QSelect.Eof do begin //UpdateInfoItem.AddIDGuid(SrcBase.QSelect.Fields[0].AsInteger, SrcBase.QSelect.Fields[1].AsString); UpdateInfoItem.IDListToMakeUpdate.Add(SrcBase.QSelect.Fields[0].AsInteger); UpdateInfoItem.IDListToMakeUpdateSorted.Add(SrcBase.QSelect.Fields[0].AsInteger); UpdateInfoItem.GUIDListToMakeUpdate.Add(SrcBase.QSelect.Fields[1].AsString); UpdateInfoItem.GUIDListToMakeUpdateSorted.Add(SrcBase.QSelect.Fields[1].AsString); SrcBase.QSelect.Next; end; if cbIncludeComponsWithProps.Checked then SelectComponsByElement(tnCompPropRelation, fnIDProperty, UpdateInfoProperty, UpdateInfoCompPropRelAfter); AddToProtocol('Найдено '+IntToStr(UpdateInfoItem.IDListToMakeUpdate.Count)+' компонентов', ProtocolIndent); StepProgress; {//31.10.2012 // Закидываем специфические данные для определенной версии базы SetRecordByVersion; // Если есть доп. инфа с данными, то перекидываем ее в основную инфу for j := AdditionUpdateInfo.Count - 1 downto 0 do begin AdditionUpdateInfoItem := AdditionUpdateInfo[j]; if AdditionUpdateInfoItem.IDListToMakeUpdateSorted.Count > 0 then begin MakeUpdateParams.FUpdateInfoItems.Add(AdditionUpdateInfoItem); AdditionUpdateInfo.OwnsObjects := false; try AdditionUpdateInfo.Delete(j); finally AdditionUpdateInfo.OwnsObjects := true; end; end else AdditionUpdateInfo.Delete(i); end; //31.10.2012 } // Если есть компоненты if (UpdateInfoItem.IDListToMakeUpdate.Count > 0) or (UpdateInfoComponBeEmptyAfter.IDListToMakeUpdateSorted.Count > 0) or (AdditionUpdateInfo.Count > 0) then begin //31.10.2012 - Если есть компоненты if (UpdateInfoItem.IDListToMakeUpdate.Count > 0) or (UpdateInfoComponBeEmptyAfter.IDListToMakeUpdateSorted.Count > 0) then begin // Определяем папки для компонентов UpdateInfoCatalog := TUpdateInfoItem.Create(nil); UpdateInfoCatalog.TableName := tnCatalog; MakeUpdateParams.FUpdateInfoItems.Add(UpdateInfoCatalog); UpdateInfoCatalogRelation := TUpdateInfoItem.Create(nil); UpdateInfoCatalogRelation.TableName := tnCatalogRelation; MakeUpdateParams.FUpdateInfoItems.Add(UpdateInfoCatalogRelation); end; // Если есть справочные свойства - кидаем их в список //if UpdateInfoProperty.IDListToMakeUpdateSorted.Count > 0 then // MakeUpdateParams.FUpdateInfoItems.Add(UpdateInfoProperty) //else // FreeAndNil(UpdateInfoProperty); ////31.10.2012 - Перенесли выше, так как не всегда могут присутствовать компоненты, иногда только справочники SetRecordByVersion; // Если есть доп. инфа с данными, то перекидываем ее в основную инфу for j := AdditionUpdateInfo.Count - 1 downto 0 do begin AdditionUpdateInfoItem := AdditionUpdateInfo[j]; if AdditionUpdateInfoItem.IDListToMakeUpdateSorted.Count > 0 then begin MakeUpdateParams.FUpdateInfoItems.Add(AdditionUpdateInfoItem); AdditionUpdateInfo.OwnsObjects := false; try AdditionUpdateInfo.Delete(j); finally AdditionUpdateInfo.OwnsObjects := true; end; end else AdditionUpdateInfo.Delete(i); end; TopCatalogIDs := TIntList.Create; IDVirtualCompons := TIntList.Create; //31.10.2012 - Если есть компоненты if (UpdateInfoItem.IDListToMakeUpdate.Count > 0) or (UpdateInfoComponBeEmptyAfter.IDListToMakeUpdateSorted.Count > 0) then begin // Для каждого компонента ищем путь папок по 1 уровень (содеожимое "Пользовательская база") j := 0; while j <= (UpdateInfoItem.IDListToMakeUpdate.Count - 1) do begin PathID := GetComponCatalogOwnerPathIDByLevel(UpdateInfoItem.IDListToMakeUpdate[j], 1, SrcBase.QSelect); if PathID <> nil then begin if PathID.Count > 0 then if Not cbOnlyVirtualCompons.Checked then begin if TopCatalogIDs.IndexOf(PathID[0]) = -1 then TopCatalogIDs.Add(PathID[0]); IDComponent := UpdateInfoItem.IDListToMakeUpdate[j]; IDCatalog := PathID[PathID.Count-1]; // Получаем ID GUID для catalog_relation SetSQLToFIBQuery(SrcBase.QSelect, GetSQLByParams(qtSelect, tnCatalogRelation, '('+fnIDCatalog+' = '''+IntToStr(IDCatalog)+''') and ('+fnIDComponent+' = '''+IntToStr(IDComponent)+''')', nil, fnID+', '+fnGuid)); if SrcBase.QSelect.RecordCount > 0 then UpdateInfoCatalogRelation.AddIDGuid(SrcBase.QSelect.Fields[0].AsInteger, SrcBase.QSelect.Fields[1].AsString); // путь папок заносим в список SetSQLToFIBQuery(SrcBase.QSelect, GetSQLByParams(qtSelect, tnCatalog, fnID+' = :'+fnID, nil, fnGUID), false); for k := 0 to PathID.Count - 1 do begin // ищем GUID SrcBase.QSelect.Close; SrcBase.QSelect.Params[0].AsInteger := PathID[k]; SrcBase.QSelect.ExecQuery; UpdateInfoCatalog.AddIDGuid(PathID[k], SrcBase.QSelect.Fields[0].AsString); end; end else begin RemoveFromUpdateInfoItem(UpdateInfoItem, j); Continue; //// CONTINUE //// end; FreeAndNil(PathID); end else begin IsVirtualCompon := biFalse; // Проверяем не виртуальный компонент ли это if cbIncludeVirtualCompons.Checked then begin IsVirtualCompon := GetIntFromTableByID(tnComponent, fnIsTemplate, UpdateInfoItem.IDListToMakeUpdate[j], SrcBase.QSelect); end; if IsVirtualCompon = biFalse then begin {UpdateInfoItem.IDListToMakeUpdateSorted.Remove(UpdateInfoItem.IDListToMakeUpdate[j]); UpdateInfoItem.GUIDListToMakeUpdateSorted.Delete( UpdateInfoItem.GUIDListToMakeUpdateSorted.IndexOf(UpdateInfoItem.GUIDListToMakeUpdate[j])); UpdateInfoItem.IDListToMakeUpdate.Delete(j); UpdateInfoItem.GUIDListToMakeUpdate.Delete(j);} RemoveFromUpdateInfoItem(UpdateInfoItem, j); Continue; //// CONTINUE //// end else IDVirtualCompons.Add(UpdateInfoItem.IDListToMakeUpdate[j]); end; j := j + 1; end; // Запрещаем подгрузку связанных объектов для catalog и catalog_relation UpdateInfoCatalogRelation.LookedIDs.Assign(UpdateInfoCatalogRelation.IDListToMakeUpdate); UpdateInfoCatalog.LookedIDs.Assign(UpdateInfoCatalog.IDListToMakeUpdate); SrcBase.Close; AddToProtocol('Добавлено '+IntToStr(UpdateInfoItem.IDListToMakeUpdate.Count)+' компонентов', ProtocolIndent); AddToProtocol('Добавлено '+IntToStr(UpdateInfoCatalog.IDListToMakeUpdate.Count + 1)+' папок', ProtocolIndent); StepProgress; end; UpdateMaker := TBaseUpdateMaker.Create; MakeUpdateResults := UpdateMaker.MakeUpdate(SrcBasePath, NBEmtyPath, TrgBasePath, MakeUpdateParams, false); FreeAndNil(UpdateMaker); if ubrSuccessful in MakeUpdateResults then begin TrgBase.Open(TrgBasePath); FieldNames := TStringList.Create; TrgBase.LoadSettings; if TopCatalogIDs.Count > 0 then begin // создаем верхнюю папку FieldNames.Clear; FieldNames.Add(fnName); FieldNames.Add(fnSortID); FieldNames.Add(fnKolCompon); FieldNames.Add(fnItemsCount); FieldNames.Add(fnIDItemType); SetSQLToFIBQuery(TrgBase.QOperat, GetSQLByParams(qtInsert, tnCatalog, '', FieldNames, ''), false); TrgBase.QOperat.ParamByName(fnName).AsString := GT_Bases.DataController.Values[i, GT_BasesCatalogName.Index]; TrgBase.QOperat.ParamByName(fnSortID).AsInteger := 1; TrgBase.QOperat.ParamByName(fnKolCompon).AsInteger := 0; TrgBase.QOperat.ParamByName(fnItemsCount).AsInteger := TopCatalogIDs.Count; TrgBase.QOperat.ParamByName(fnIDItemType).AsInteger := itDir; TrgBase.QOperat.ExecQuery; IDTopCatalog := GenIDFromTable(TrgBase.QSelect, gnKatalogID, 0); // Привязываем папки в верхней SetSQLToFIBQuery(TrgBase.QOperat, GetSQLByParams(qtUpdate, tnCatalog, fnID+' = :'+fnID, nil, fnParentID), false); for j := 0 to TopCatalogIDs.Count - 1 do begin TrgBase.QOperat.Close; TrgBase.QOperat.Params[0].AsInteger := IDTopCatalog; TrgBase.QOperat.Params[1].AsInteger := TopCatalogIDs[j]; TrgBase.QOperat.ExecQuery; end; TrgBase.FSettings.DBType := dbtCatalog; end else TrgBase.FSettings.DBType := dbtUpdate; TrgBase.SaveSettings; // Добавляем пустые компоненты из списка + каждому ставим признак "Только обновлять если не пусто" FieldNames.Clear; FieldNames.Add(fnID); FieldNames.Add(fnGuid); FieldNames.Add(fnActRowLimit); // Скрипт добавления SetSQLToFIBQuery(TrgBase.QOperat, GetSQLByParams(qtInsert, tnComponent, '', FieldNames, ''), false); // Скрипт проверки SetSQLToFIBQuery(TrgBase.QSelect, GetSQLByParams(qtSelect, tnComponent, fnID+' = :'+fnID, nil, fnID), false); for j := 0 to UpdateInfoComponBeEmptyAfter.IDListToMakeUpdate.Count - 1 do begin TrgBase.QSelect.Close; TrgBase.QSelect.Params[0].AsInteger := UpdateInfoComponBeEmptyAfter.IDListToMakeUpdate[j]; TrgBase.QSelect.ExecQuery; if TrgBase.QSelect.RecordCount = 0 then begin TrgBase.QOperat.Close; TrgBase.QOperat.Params[0].AsInteger := UpdateInfoComponBeEmptyAfter.IDListToMakeUpdate[j]; TrgBase.QOperat.Params[1].AsString := UpdateInfoComponBeEmptyAfter.GUIDListToMakeUpdate[j]; TrgBase.QOperat.Params[2].AsInteger := alrSkip; TrgBase.QOperat.ExecQuery; end; end; // Виртуальным комопнентам ставим признак, что они только на добавление если нету if IDVirtualCompons.Count > 0 then begin // Скрипт Обновления SetSQLToFIBQuery(TrgBase.QOperat, GetSQLByParams(qtUpdate, tnComponent, fnID+' = :'+fnID, nil, fnActRowLimit), false); for j := 0 to IDVirtualCompons.Count - 1 do begin TrgBase.QOperat.Close; TrgBase.QOperat.Params[0].AsInteger := alrInsIfNoExist; TrgBase.QOperat.Params[1].AsInteger := IDVirtualCompons[j]; TrgBase.QOperat.ExecQuery; end; end; if UpdateInfoCompPropRelAfter.IDListToMakeUpdate.Count > 0 then begin // Убираем из списка те, что уже есть в блоке SetSQLToFIBQuery(TrgBase.QSelect, GetSQLByParams(qtSelect, UpdateInfoCompPropRelAfter.TableName, fnID+' = :'+fnID, nil, fnID), false); for j := UpdateInfoCompPropRelAfter.IDListToMakeUpdate.Count -1 downto 0 do begin TrgBase.QSelect.Close; TrgBase.QSelect.Params[0].AsInteger := UpdateInfoCompPropRelAfter.IDListToMakeUpdate[j]; TrgBase.QSelect.ExecQuery; if TrgBase.QSelect.RecordCount > 0 then begin UpdateInfoCompPropRelAfter.IDListToMakeUpdateSorted.Remove(UpdateInfoCompPropRelAfter.IDListToMakeUpdate[j]); ItemIndex := UpdateInfoCompPropRelAfter.GUIDListToMakeUpdateSorted.IndexOf(UpdateInfoCompPropRelAfter.GUIDListToMakeUpdate[j]); if ItemIndex <> -1 then UpdateInfoCompPropRelAfter.GUIDListToMakeUpdateSorted.Delete(ItemIndex); UpdateInfoCompPropRelAfter.IDListToMakeUpdate.Delete(j); UpdateInfoCompPropRelAfter.GUIDListToMakeUpdate.Delete(j); end; end; // Докидываем данные таблиц TrgBase.Close; UpdateMaker := TBaseUpdateMaker.Create; //UpdateMaker.SrcBase.Open(SrcBasePath); //UpdateMaker.DestBase.Open(TrgBasePath); UpdateMaker.SrcBase := SrcBase; UpdateMaker.DestBase := TrgBase; UpdateMaker.SrcBase.Open(SrcBasePath); UpdateMaker.DestBase.Open(TrgBasePath); try UpdateMaker.SetSrcTableIDs(UpdateInfoCompPropRelAfter); UpdateMaker.InsertSrcTableToDest(UpdateInfoCompPropRelAfter); //-------------------------------- Begin //27.01.2013 - //// Свойствам ставим признак, что они добавляются только в том случае, если таких нету //UpdateTableIntFieldRecsFromListID(UpdateMaker.DestBase.QOperat, // UpdateInfoCompPropRelAfter.TableName, fnActRowLimit, alrInsIfNoExist, // UpdateInfoCompPropRelAfter.IDListToMakeUpdate); //27.01.2013 - временно признак ставим от флага cbAllowEditDate (также по дате редактирования) - если снят то только вносить если нету свойств // если флаг есть, то позволять обновлять // в идеале нужно сделать проверку на каждую запись - если запись была создана до dtFrom, то позволять обновлять (alrUpdAllow), иначе только вносить как новую (alrInsIfNoExist) ActRowLimit := alrInsIfNoExist; if Not cbAllowEditDate.Checked then begin //ActRowLimit := alrUpdAllow; UpdateTableIntFieldRecsFromListID(UpdateMaker.DestBase.QOperat, UpdateInfoCompPropRelAfter.TableName, fnActRowLimit, ActRowLimit, UpdateInfoCompPropRelAfter.IDListToMakeUpdate); end; //--------------------------------- End finally UpdateMaker.SrcBase := nil; UpdateMaker.DestBase := nil; end; FreeAndNil(UpdateMaker); end; FieldNames.Free; SrcBase.Close; TrgBase.Close; TrgBase.PackBase(TrgBasePath, TrgBase.ConnectParams); RenameFile(TrgBasePath, TrgBasePath); end; StepProgress; FreeAndNil(IDVirtualCompons); FreeAndNil(TopCatalogIDs); end else begin CopyFileToByName(NBEmtyPath, TrgBasePath); StepProgress; StepProgress; end; StepProgress; //MakeUpdateParams.FUpdateInfoItems.Remove(UpdateInfoItem); //FreeAndNil(UpdateInfoItem); FreeAndNil(UpdateInfoComponBeEmptyAfter); FreeAndNil(AdditionUpdateInfo); FreeAndNil(MakeUpdateParams); except on E: Exception do begin AddExceptionToLogEx('ProcName', E.Message); AddToProtocol('Ошибка обработка базы '+E.Message, ProtocolIndent); end; end; end; CurrTick := GetTickCount - OldTick; ProtocolIndent := 0; AddToProtocol('Готово (за '+FloatToStr(CurrTick/1000)+' сек)', ProtocolIndent); finally EndProgress; end; finally SrcBase.Free; TrgBase.Free; end; finally TF_Main(GForm).GSCSBase.SimpleOpen(true); end; end; end; procedure TF_MakeUpdateBlock.Button1Click(Sender: TObject); var MakeUpdateBlockSettings: TMakeUpdateBlockSettings; Stream: TFileStream; begin MakeUpdateBlockSettings := TMakeUpdateBlockSettings.Create(nil); MakeUpdateBlockSettings.FDirName := 'update'; //'Обновление'; Stream := TFileStream.Create('c:\111.txt', fmCreate); Stream.WriteComponent(MakeUpdateBlockSettings); Stream.Free; MakeUpdateBlockSettings.Free; end; function TF_MakeUpdateBlock.GetSQLConditionByDates: String; begin Result := '(date_in between '''+DateToStr(dtFrom.Date)+''' and '''+DateToStr(dtTo.Date)+''')'; if cbAllowEditDate.Checked then Result := Result + ' OR (date_mod between '''+DateToStr(dtFrom.Date)+''' and '''+DateToStr(dtTo.Date)+''')'; end; end.