unit U_MasterUpdatePrice;

interface

uses
  Windows, U_LNG, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, RzPanel, RzTabs, RzButton,
  StdCtrls, Mask, RzEdit, Buttons, Contnrs, XLSFile, XLSWorkbook, XLSFormat, XLSRects,

  U_BaseCommon, U_BaseConstants, U_Common, U_SCSComponent, U_SCSLists, Grids, RzCommon, RzCmboBx, RzRadChk, exgrid, RapTree,
  FlytreePro, Treecoll, IsPlugEdit, ispinedit, FIBQuery, pFIBQuery, Menus, XPMenu,
  siComp, siLngLnk, ComCtrls, RzListVw, RzStatus, cxStyles, cxCustomData,
  cxGraphics, cxFilter, cxData, cxDataStorage, cxEdit, DB, cxDBData,
  cxMemo, cxCheckBox, cxCurrencyEdit, cxColorComboBox, cxSpinEdit,
  cxTextEdit, cxGridLevel, cxGridCustomTableView, cxGridTableView,
  cxGridDBTableView, cxClasses, cxControls, cxGridCustomView, cxGrid,
  cxDropDownEdit, kbmMemTable, cxDBLookupComboBox, cxContainer, cxMaskEdit, U_Constants,
  U_Common_Classes, cxLookAndFeels, cxLookAndFeelPainters, cxNavigator;

const
  // Column index
  ciArtNo = 0;
  ciCypher = 1;
  ciName = 2;
  ciIzm = 3;
  ciCurrPrice = 4;
  ciNewPriceInXFCurrency = 5;
  ciNewPriceInComponCurrency = 6;
  ciNewName = 7;
  ciResType = 8;

  //Menu Indexes
  miComponArtNo    = 0;
  miComponPrice    = 1;
  miNormResCypher  = 2;
  miNormResName    = 3;
  miNormResIzm     = 4;
  miResPrice       = 5;
  miResType        = 6;
  miName           = 7;
  miIzm            = 8;
  miStructLevel    = 9;

  cntStructLevels = 6;
  

type
  TTabXFSheetInfo = class
    private
      FOwner: TRzTabSheet;
      FGrid: TStringGrid;
    public
      IsLoadedSheet: Boolean;
      //ArtNoColumIndex: Integer;
      //PriceColumIndex: Integer;
      //NameColumIndex: Integer;
      //ArtNoType: TArtNoType;

      SheetIndex: Integer;
      ColumnCount: Integer;
      ColumnContextPopup: Integer;
      RowCount: integer;
      RowContextPopup: Integer;

      RelatedObject: TObject;

    constructor Create(AOwner: TRzTabSheet);
    destructor Destroy; override;
  end;

  TXLSPreview = class(TMyObject)
    private
      FParentControl: TWinControl;

      FObjectList: TObjectList;
      FpcXFSheets: TRzPageControl;
      FPopupMenu: TPopupMenu;

      Fxf: TXLSFile;
      FFileName: String;
      FXFSheetPopupPoint: TPoint;
      FActiveTabXFSheetInfo: TTabXFSheetInfo;

      FControlsRelatedToMenuItems: TObjectList;

      FOwnsRelatedObjectsToSheetInfo: Boolean;
      FOnCreateSheetInfo: TNotifyEvent;
      FOnChangeSheet: TNotifyEvent;
      FOnMenuItemClick: TNotifyEvent;

      procedure ClearPages;

      // Определяет назначение колонок для листа
      procedure DefineSheetColumns(ATabXFSheetInfo: TTabXFSheetInfo);
      procedure FpcXFSheetsChange(Sender: TObject);
      procedure FPopupMenuItemClick(Sender: TObject);
      procedure XFSheetContextPopup(Sender: TObject; MousePos: TPoint;
        var Handled: Boolean);
    public
      property OwnsRelatedObjectsToSheetInfo: Boolean read FOwnsRelatedObjectsToSheetInfo write FOwnsRelatedObjectsToSheetInfo;
      property ActiveTabXFSheetInfo: TTabXFSheetInfo read FActiveTabXFSheetInfo;
      property OnCreateSheetInfo: TNotifyEvent read FOnCreateSheetInfo write FOnCreateSheetInfo;
      property OnChangeSheet: TNotifyEvent read FOnChangeSheet write FOnChangeSheet;
      property OnMenuItemClick: TNotifyEvent read FOnMenuItemClick write FOnMenuItemClick;
      property pcXFSheets: TRzPageControl read FpcXFSheets;
      property Xf: TXLSFile read Fxf;
      property FileName: String read FFileName;

      function AddMenuItem(ACaption: String; ATag: Integer; ARelatedControl: TWinControl=nil): TMenuItem;
      procedure AddRelatedControlWithMenuItem(AControl: TWinControl; ATag: Integer);
      function GetRelatedControlWithMenuItemByTag(ATag: Integer): TWinControl;

      procedure ClearMenuItems;
      constructor Create(AParent: TWinControl; AOwnsRelatedObjectsToSheetInfo: Boolean);
      destructor Destroy; override;
      function OpenFromFile(AFileName: string): Boolean;
      procedure Close;
      procedure ShowXLS;
  end;

  TSheetComponPropsInfo = class(TMyObject)
    private
      procedure AddRowToMT(const ASysName, ACaption: String; AColumn: String='');
      procedure AddCompPropToMT(const APropSysName: String);
    public
      ArtNoColumIndex: Integer;
      PriceColumIndex: Integer;
      NameColumIndex: Integer;
      IzmColumIndex: Integer;
      ArtNoType: TArtNoType;

      NormResCypherColumIndex: Integer;
      NormResNameColumIndex: Integer;
      NormResIzmColumIndex: Integer;
      ResPriceColumIndex: Integer;
      ResTypeColumIndex: Integer;

      StructLevelsIndex: TIntList;
      FMT: TkbmMemTable;
      FDataSource: TDataSource;

      constructor Create;
      destructor Destroy; override;
      procedure DefineColumnsNums;
  end;

  TStepSheetInfo = class(TObject)
    public
      FSheetOwner: TRzTabSheet;
      FPanelCaption: TRzPanel;
      FCaptionValue: String;
  end;

  TXLSRowInfo = class(TMyObject)
    public
      FArtNo: string;
      FName: string;
      FPrice: Double;
      FIzm: string;

      FRowIndex: Integer;

      FCatalogs: TStringList;
      FPropValues: TStringList;

      constructor Create;
      destructor Destroy; override;
  end;

  TNodeObjectInfo = class(TMyObject)
    private
      FOwner: TFlyNode;
    public
      ID: Integer;
      ArtNo: string;
      Name: string;
      CurrPrice: Double;
      IDComponType: Integer;

      IsTransformPrice: Boolean;
      NewPriceInComponCurrency: Double;
      NewPriceInXFCurrency: Double;
      NewName: String;
      Cypher: String;
      Izm: String;
      ResType: Integer;

      CurrencyM: TCurrency;
      CurrencyXF: TCurrency;

      FRowIndex: Integer;
      FCatalogs: TStringList;

      constructor Create(AOwner: TFlyNode);
      destructor Destroy; override;
  end;

  TF_MasterUpdatePrice = class(TForm)
    pcUpdatePrice: TRzPageControl;
    gbNavigator: TRzGroupBox;
    btBack: TRzButton;
    btNext: TRzButton;
    btCancel: TRzButton;
    tsSelectFileName: TRzTabSheet;
    tsSelectColums: TRzTabSheet;
    Label1: TLabel;
    edFileNameXls: TRzEdit;
    btSelectXlsFile: TSpeedButton;
    gbXLSDoc: TRzGroupBox;
    pcXFSheets: TRzPageControl;
    TabSheet1: TRzTabSheet;
    TabSheet2: TRzTabSheet;
    TabSheet3: TRzTabSheet;
    pnCaption1: TRzPanel;
    pnCaption2: TRzPanel;
    gbSheetProps: TRzGroupBox;
    RzPanel2: TRzPanel;
    Timer_OnExecute: TTimer;
    tsSelectCurrency: TRzTabSheet;
    pnCaption3: TRzPanel;
    Label3: TLabel;
    cbCurrency: TRzComboBox;
    btSelectCurrency: TSpeedButton;
    tsSelectComponents: TRzTabSheet;
    pnCaption4: TRzPanel;
    RzPanel1: TRzPanel;
    btUpdatePrices: TRzBitBtn;
    tvComponents: TFlyTreeViewPro;
    StringGrid1: TStringGrid;
    cbSelectCurrComponInNB: TRzCheckBox;
    btCheckAllCompons: TSpeedButton;
    btUnCheckAllCompons: TSpeedButton;
    pmnuXFList: TPopupMenu;
    pmiSetColAsArticul: TMenuItem;
    pmiSetColAsPrice: TMenuItem;
    lng_Forms: TsiLangLinked;
    gbWorVerisonParams: TRzGroupBox;
    Label5: TLabel;
    cbColumnName: TRzComboBox;
    RzPanel3: TRzPanel;
    lbNoticeCurrUOM: TLabel;
    pcSheetProps: TRzPageControl;
    tsUpdateComponSheetProps: TRzTabSheet;
    tsImportNormResSheetProps: TRzTabSheet;
    pnUpdateComponSheetProps: TRzPanel;
    Label2: TLabel;
    Label4: TLabel;
    cbColumnArtNo: TRzComboBox;
    cbColumnPrice: TRzComboBox;
    RzGroupBox3: TRzGroupBox;
    rbArtNoProduc: TRzRadioButton;
    rbArtNoDistrib: TRzRadioButton;
    pnImportNormResSheetProps: TRzPanel;
    pnImportNormSheetProps: TRzPanel;
    lbNormResCypher: TLabel;
    cbNormResCypher: TRzComboBox;
    lbNormResName: TLabel;
    cbNormResName: TRzComboBox;
    lbNormResIzm: TLabel;
    cbNormResIzm: TRzComboBox;
    pnImportResSheetProps: TRzPanel;
    Label10: TLabel;
    cbResPrice: TRzComboBox;
    lbResType: TLabel;
    cbResType: TRzComboBox;
    pnUOMForLine: TPanel;
    Label6: TLabel;
    cbUOM: TRzComboBox;
    gbExistsObjects: TRzGroupBox;
    lvExistsObjects: TRzListView;
    spExistsObjects: TSplitter;
    cbSmartCompareArtNo: TCheckBox;
    sbComponsInfo: TRzStatusBar;
    fsComponCountExists: TRzFieldStatus;
    fsComponCountLack: TRzFieldStatus;
    Label7: TLabel;
    cbColumnIzm: TRzComboBox;
    RzGroupBox1: TRzGroupBox;
    Label8: TLabel;
    cbStructLevel1: TRzComboBox;
    Label9: TLabel;
    cbStructLevel2: TRzComboBox;
    Label11: TLabel;
    cbStructLevel3: TRzComboBox;
    Label12: TLabel;
    cbStructLevel4: TRzComboBox;
    Label13: TLabel;
    cbStructLevel5: TRzComboBox;
    Label14: TLabel;
    cbStructLevel0: TRzComboBox;
    RzGroupBox2: TRzGroupBox;
    Grid_PropColumns: TcxGrid;
    GT_PropColumns: TcxGridDBTableView;
    GT_PropColumnsCaption: TcxGridDBColumn;
    GT_PropColumnsColumn: TcxGridDBColumn;
    GL_PropColumns: TcxGridLevel;
    cbApplyStructureForExist: TRzCheckBox;
    cbAddLackCompons: TRzCheckBox;
    cbApplyParamsFroExist: TRzCheckBox;
    DefPrice: TRzEdit;
    EdtStartPos: TRzEdit;
    Label15: TLabel;
    cbAutoAddInter: TCheckBox;
    cbLoadFromCompType: TCheckBox;
    ComboCompType: TcxComboBox;
    cbAddToDescr: TCheckBox;
    XPMenu: TXPMenu;
    procedure gbNavigatorResize(Sender: TObject);
    procedure pcUpdatePriceChange(Sender: TObject);
    procedure btBackClick(Sender: TObject);
    procedure btNextClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure btSelectXlsFileClick(Sender: TObject);
    procedure pcXFSheetsChange(Sender: TObject);
    procedure Timer_OnExecuteTimer(Sender: TObject);
    procedure cbColumnArtNoChange(Sender: TObject);
    procedure cbColumnPriceChange(Sender: TObject);
    procedure rbArtNoProducClick(Sender: TObject);
    procedure rbArtNoDistribClick(Sender: TObject);
    procedure btSelectCurrencyClick(Sender: TObject);
    procedure cbCurrencyChange(Sender: TObject);
    procedure btUpdatePricesClick(Sender: TObject);
    procedure cbSelectCurrComponInNBClick(Sender: TObject);
    procedure tvComponentsSelectedChanged(OldNode, NewNode: TFlyNode);
    procedure btCheckAllComponsClick(Sender: TObject);
    procedure btUnCheckAllComponsClick(Sender: TObject);
    procedure tvComponentsStateChanging(Node: TFlyNode;
      var AllowChange: Boolean);
    procedure pmiSetColAsArticulClick(Sender: TObject);
    procedure pmiSetColAsPriceClick(Sender: TObject);
    procedure cbColumnNameChange(Sender: TObject);
    procedure cbUOMChange(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure cbColumnSheetParamChange(Sender: TObject);
    procedure lvExistsObjectsSelectItem(Sender: TObject; Item: TListItem;
      Selected: Boolean);
    procedure tvComponentsCloseUp(Sender: TISPlugInplaceEdit;
      Section: TISPlugSection; DropDown: TISDropDown; var Accept: Boolean);
    procedure pmiSetColAsIzmClick(Sender: TObject);
    procedure GT_PropColumnsColumnPropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption;
      var Error: Boolean);
    procedure cbLoadFromCompTypeClick(Sender: TObject);
    procedure fsComponCountLackDblClick(Sender: TObject);
    procedure fsComponCountExistsDblClick(Sender: TObject);
  private
    GForm: TForm;
    FFromForm: TForm;
    //Fxf: TXLSFile;
    FXLSPreview: TXLSPreview;
    FIsOpenedXlsFile: Boolean;
    FIsLoadedXlsFile: Boolean;
    FIsLoadedCurrency: Boolean;
    FISLoadedComponents: Boolean;
    FISLoadedComponentPrices: Boolean;
    FISLoadedResources: Boolean;
    FISLoadedResourcePrices: Boolean;
    FISLoadedNorms: Boolean;
    FOpenedFileName: string;
    FXLSUOM: Integer;

    //FActiveTabXFSheetInfo: TTabXFSheetInfo;
    FActiveSheetComponPropsInfo: TSheetComponPropsInfo;
    FActiveCurrency: TCurrency;

    FXFSheetPopupPoint: TPoint;

    FFormMode: TMasterUpdatePriceMode;
    FStepSheets: TObjectList;
    FPanelWithSheetParams: TRzPanel;
    //FControlsRelatedToMenuItems: TObjectList;

    FAllSuppliesKinds: TList;
    FReloadNBTree: Boolean;

    procedure AddUpdateComponToNB(ATrgCatalog: TSCSCatalog; AComponInfo: TNodeObjectInfo);
    procedure AddNormResInfoToListView(const ACypher, AName, AIzm: String; AID: Integer; AListView: TRzListView);
    //procedure AddRelatedControlWithMenuItem(AControl: TWinControl; ATag: Integer);
    //function CutBeginZeroDefisInArticle(const AArtNo: String): String;
    procedure DropAllSelections;
    procedure DropSelectionForFile;
    procedure DropSelectionForSheet;
    procedure DropSelectionForPrices;
    procedure ClearNodes;
    procedure ClearStepSheetInfo;
    procedure ClearXlsDataFromForm;
    procedure CreateColumnsInListView(AListView: TRzListView; AColNames: TStringList; AWidthList: TIntList);
    procedure CreateColumnsInListViewFromTVColumns(AListView: TRzListView; ATree: TFlyTreeViewPro; AColIndexes: array of Integer);
    function CreateStepSheetInfo(ATabSheet: TRzTabSheet; APanelCaption: TRzPanel): TStepSheetInfo;
    function GetCurrStepIndex: Integer;
    function GetPriceInXLSUOM(APrice: Double; ANodeComponInfo: TNodeObjectInfo): Double;
    function GetPriceInNBUOM(APrice: Double; ANodeComponInfo: TNodeObjectInfo): Double;
    function GetStructLevelCombo(ALevelNum: Integer): TRZComboBox;
    function GetStructLevelFromName(const AName, ANamePrefix: string): Integer;
    //function GetRelatedControlWithMenuItemByTag(ATag: Integer): TWinControl;
    procedure ImportNormResToBase;
    procedure LoadColumnsToStrings(AStrings: TStrings; AColumnCount: Integer);
    procedure LoadComponentsFromXF;
    procedure LoadComponPricesFromXF;
    procedure LoadCurrencies(AGUIDToSelect: String);
    procedure LoadNormsFromXF;
    procedure LoadPropsToCompon(AComponent: TSCSComponent; AComponInfo: TNodeObjectInfo; AChangedProp, AChangedCompType, AChangedCCE: PBoolean);
    procedure LoadResourcesFromXF;
    procedure LoadResourcePricesFromXF;
    procedure LoadSelectedColumnFromSheetInfo(ADestCombo: TRzComboBox; ASelColumnIndex: Integer; ASrcTabXFSheetInfo: TTabXFSheetInfo);
    procedure LoadXlsFileToForm;
    procedure SelectCurrComponentInNB;
    procedure SetActiveCurrencyByGUID(AGUID: string);
    procedure SetCaptionToStepPages;
    procedure SetControls;
    procedure SetSateToAllComponNodes(AState: Integer);
    procedure UpdatePrices;
    procedure XFSheetContextPopup(Sender: TObject; MousePos: TPoint;
      var Handled: Boolean);

    procedure FXLSPreviewCreateSheetInfo(Sender: TObject);
    procedure FXLSPreviewChangeSheet(Sender: TObject);
    procedure FXLSPreviewMenuItemClick(Sender: TObject);
  public
    FInsertedDirTypeID: Integer;

    Constructor Create(AOwner: TComponent; AForm: TForm);
    Destructor  Destroy; override;
    function Execute(AFormMode: TMasterUpdatePriceMode; AFromForm: TForm): Boolean;
    //function CutBeginZeroDefisInArticle(const AArtNo: String): String;
  end;

//var
  //F_MasterUpdatePrice: TF_MasterUpdatePrice;
var
  NoFindedArticles: TStringList;
  FindedArticles: TStringList;

implementation
Uses U_Main, Unit_DM_SCS;
{$R *.dfm}

{ TTabXFSheetInfo }

constructor TTabXFSheetInfo.Create(AOwner: TRzTabSheet);
begin
  FOwner := AOwner;

  IsLoadedSheet := false;
  //ArtNoColumIndex := -1;
  //PriceColumIndex := -1;
  //NameColumIndex := -1;
  //ArtNoType := antProduc;

  SheetIndex := -1;
  ColumnCount := 0;
  RowCount := 0;

  RelatedObject := nil;

  FGrid := nil;
  if FOwner <> nil then
  begin
    FGrid := TStringGrid.Create(nil);
    FGrid.Parent := FOwner;
    FGrid.Align := alClient;
    FGrid.Font.Size := 8;
    FGrid.Options := FGrid.Options + [Grids.goColSizing, Grids.goRowSizing];
  end;
end;

destructor TTabXFSheetInfo.Destroy;
begin
  if Assigned(FGrid) then
    FreeAndNil(FGrid);

  inherited;
end;

{ TXLSRowInfo }

constructor TXLSRowInfo.Create;
begin
  inherited;

  FArtNo := '';
  FName := '';
  FPrice := 0;
  FIzm := '';

  FRowIndex := -1;

  FCatalogs := TStringList.Create;
  FPropValues := TStringList.Create;
end;

destructor TXLSRowInfo.Destroy;
begin
  FCatalogs.Free;

  RemoveGUIDIDFromStrings(FPropValues);
  FPropValues.Free;

  inherited;
end;


{ TNodeObjectInfo }

constructor TNodeObjectInfo.Create(AOwner: TFlyNode);
begin
  inherited create;
  FOwner := AOwner;

  ID := 0;
  ArtNo := '';
  Name := '';
  CurrPrice := 0;
  IDComponType := 0;

  IsTransformPrice := false;
  NewPriceInComponCurrency := 0;
  NewPriceInXFCurrency := 0;
  NewName := '';

  Cypher := '';
  Izm := '';
  ResType := -1;

  FRowIndex := -1;

  ZeroMemory(@CurrencyM, SizeOf(TCurrency));
  ZeroMemory(@CurrencyXF, SizeOf(TCurrency));

  FCatalogs := TStringList.Create;
end;


destructor TNodeObjectInfo.Destroy;
begin
  FreeAndNil(FCatalogs);
  inherited;
end;

{ TF_MasterUpdatePrice }

constructor TF_MasterUpdatePrice.Create(AOwner: TComponent; AForm: TForm);
begin
  if FindedArticles = nil then
    FindedArticles := TStringList.Create;
  if NoFindedArticles = nil then
    NoFindedArticles := TStringList.Create;
  GForm := AForm;
  inherited Create(AOwner);
end;

destructor TF_MasterUpdatePrice.Destroy;
begin
  inherited;
end;

function TF_MasterUpdatePrice.Execute(AFormMode: TMasterUpdatePriceMode; AFromForm: TForm): Boolean;
var
  Combo: TRzComboBox;
  MenuItem: TMenuItem;
  i: Integer;
begin
  Result := false;
  FFormMode := AFormMode;
  FFromForm := AFromForm;
  FInsertedDirTypeID := 0;

  cbAutoAddInter.Enabled := GUseLiteFunctional;
  if cbAutoAddInter.Checked and Not GUseLiteFunctional then
    cbAutoAddInter.Checked := False;

  FXLSPreview.ClearMenuItems;
  FStepSheets.Clear;
  FPanelWithSheetParams := nil;
  tvComponents.Columns[ciNewName].Visible := false;
  pnUOMForLine.Visible := false;
  cbSelectCurrComponInNB.Visible := false;
  lbNoticeCurrUOM.Caption := '';
  // найденные объекты
  spExistsObjects.Visible := false;
  gbExistsObjects.Visible := false;


  if (lng_Forms.ActiveLanguage = 1) or (lng_Forms.ActiveLanguage = 7) then
  begin
    fsComponCountExists.FieldLabel := 'Компонентов найдено';
    fsComponCountLack.FieldLabel := 'Кол-во отсутствующих';
  end
  else
  begin
    fsComponCountExists.FieldLabel := 'Items found';
    fsComponCountLack.FieldLabel := 'Items not found';
  end;
  case AFormMode of
    fmUpdateCompons:
      begin
        Caption := cMasterUpdatePrice_Msg1;

        FStepSheets.Add(tsSelectFileName);
        FStepSheets.Add(tsSelectColums);
        FStepSheets.Add(tsSelectCurrency);
        FStepSheets.Add(tsSelectComponents);

        TStepSheetInfo(tsSelectColums.Tag).FCaptionValue := cMasterUpdatePrice_Msg9_1;
        TStepSheetInfo(tsSelectComponents.Tag).FCaptionValue := cMasterUpdatePrice_Msg9_2;

        pcSheetProps.ActivePage := tsUpdateComponSheetProps;
        FPanelWithSheetParams := pnUpdateComponSheetProps;

        cbColumnName.OnChange := cbColumnSheetParamChange;
        cbColumnIzm.OnChange := cbColumnSheetParamChange;

        FXLSPreview.AddMenuItem(cMasterUpdatePrice_Msg5_1, miComponArtNo);
        FXLSPreview.AddMenuItem(cMasterUpdatePrice_Msg5_2, miComponPrice);
        FXLSPreview.AddMenuItem(cMasterUpdatePrice_Msg5_8, miName, cbColumnName);
        FXLSPreview.AddMenuItem(cMasterUpdatePrice_Msg5_5, miIzm, cbColumnIzm);

        // Элементы меню для структуры
        FXLSPreview.AddMenuItem('-', 0);
        for i := 0 to cntStructLevels - 1 do
        begin
          Combo := GetStructLevelCombo(i); //TRzComboBox(FindComponent('cbStructLevel'+IntToStr(i)));
          if Combo <> nil then
          begin
            Combo.OnChange := cbColumnSheetParamChange;

            MenuItem := FXLSPreview.AddMenuItem(cMasterUpdatePrice_Msg11+' '+IntToStr(i+1), miStructLevel, Combo);
            MenuItem.Name := 'pmiColumnStructLevel'+IntToStr(i);
          end;
        end;

        // настройка грида
        tvComponents.Columns[ciArtNo].Visible := true;
        tvComponents.Columns[ciCypher].Visible := false;
        tvComponents.Columns[ciName].Visible := true;
        tvComponents.Columns[ciIzm].Visible := false;
        tvComponents.Columns[ciCurrPrice].Visible := true;
        tvComponents.Columns[ciNewPriceInXFCurrency].Visible := true;
        tvComponents.Columns[ciNewPriceInComponCurrency].Visible := true;
        {$IF Defined (FINAL_SCS)}
          tvComponents.Columns[ciNewName].Visible := true;
        {$IFEND}
        tvComponents.Columns[ciResType].Visible := false;
        tvComponents.Columns[ciName].Caption := cMasterUpdatePrice_Msg3_1;
        tvComponents.Columns[ciNewPriceInComponCurrency].Caption := cMasterUpdatePrice_Msg3_3;
        tvComponents.StructureCol := ciArtNo;

        // Настройка контролов
        pnUOMForLine.Visible := true;
        cbSelectCurrComponInNB.Visible := true;
      end;
    fmImportResources, fmImportNorms:       
      begin
        case AFormMode of
          fmImportResources:
            begin
              Caption := cMasterUpdatePrice_Msg1_2;

              FStepSheets.Add(tsSelectFileName);
              FStepSheets.Add(tsSelectColums);
              FStepSheets.Add(tsSelectCurrency);
              FStepSheets.Add(tsSelectComponents);

              pnImportResSheetProps.Visible := true;

              FXLSPreview.AddMenuItem(cMasterUpdatePrice_Msg5_3, miNormResCypher, cbNormResCypher);
              FXLSPreview.AddMenuItem(cMasterUpdatePrice_Msg5_4, miNormResName, cbNormResName);
              FXLSPreview.AddMenuItem(cMasterUpdatePrice_Msg5_5, miNormResIzm, cbNormResIzm);
              FXLSPreview.AddMenuItem(cMasterUpdatePrice_Msg5_6, miResPrice, cbResPrice);
              FXLSPreview.AddMenuItem(cMasterUpdatePrice_Msg5_7, miResType, cbResType);


              // настройка грида
              tvComponents.Columns[ciArtNo].Visible := false;
              tvComponents.Columns[ciCypher].Visible := true;
              tvComponents.Columns[ciName].Visible := true;
              tvComponents.Columns[ciIzm].Visible := true;
              tvComponents.Columns[ciCurrPrice].Visible := false;
              tvComponents.Columns[ciNewPriceInXFCurrency].Visible := true;
              tvComponents.Columns[ciNewPriceInComponCurrency].Visible := true;
              tvComponents.Columns[ciResType].Visible := true;
              tvComponents.Columns[ciName].Caption := lbNormResName.Caption;
              tvComponents.Columns[ciNewPriceInComponCurrency].Caption := cMasterUpdatePrice_Msg3_6;
              tvComponents.StructureCol := 0; //tvComponents.StructureCol := ciCypher;

              // Настройка контролов
              gbExistsObjects.Visible := true;
              spExistsObjects.Visible := true;
              gbExistsObjects.Caption := cMasterUpdatePrice_Msg7_2;
              CreateColumnsInListViewFromTVColumns(lvExistsObjects, tvComponents, [ciCypher, ciName, ciIzm]);
            end;
          fmImportNorms:
            begin
              Caption := cMasterUpdatePrice_Msg1_3;

              FStepSheets.Add(tsSelectFileName);
              FStepSheets.Add(tsSelectColums);
              FStepSheets.Add(tsSelectComponents);

              pnImportResSheetProps.Visible := false;

              FXLSPreview.AddMenuItem(cMasterUpdatePrice_Msg5_3, miNormResCypher, cbNormResCypher);
              FXLSPreview.AddMenuItem(cMasterUpdatePrice_Msg5_4, miNormResName, cbNormResName);
              FXLSPreview.AddMenuItem(cMasterUpdatePrice_Msg5_5, miNormResIzm, cbNormResIzm);

              // настройка грида
              tvComponents.Columns[ciArtNo].Visible := false;
              tvComponents.Columns[ciCypher].Visible := true;
              tvComponents.Columns[ciName].Visible := true;
              tvComponents.Columns[ciIzm].Visible := true;
              tvComponents.Columns[ciCurrPrice].Visible := false;
              tvComponents.Columns[ciNewPriceInXFCurrency].Visible := false;
              tvComponents.Columns[ciNewPriceInComponCurrency].Visible := false;
              tvComponents.Columns[ciResType].Visible := false;
              tvComponents.Columns[ciName].Caption := lbNormResName.Caption;
              tvComponents.StructureCol := 0; //tvComponents.StructureCol := ciCypher;

              // Настройка контролов
              gbExistsObjects.Visible := true;
              spExistsObjects.Visible := true;
              gbExistsObjects.Caption := cMasterUpdatePrice_Msg7_1;
              CreateColumnsInListViewFromTVColumns(lvExistsObjects, tvComponents, [ciCypher, ciName, ciIzm]);
            end;
        end;
        TStepSheetInfo(tsSelectColums.Tag).FCaptionValue := cMasterUpdatePrice_Msg9_3;
        TStepSheetInfo(tsSelectComponents.Tag).FCaptionValue := cMasterUpdatePrice_Msg9_4;

        Application.ProcessMessages;
        pcSheetProps.ActivePage := tsImportNormResSheetProps;
        FPanelWithSheetParams := pnImportNormResSheetProps;

        {Application.ProcessMessages;
        pnImportNormResSheetProps.AutoSize := true;
        Application.ProcessMessages;
        pnImportNormResSheetProps.AutoSize := false;
        Application.ProcessMessages;
        pnImportNormResSheetProps.AutoSize := true;
        Application.ProcessMessages;
        pnImportNormResSheetProps.AutoSize := false;}

        Application.ProcessMessages;
        pnImportNormResSheetProps.AutoSize := true;
        Application.ProcessMessages;
        pnImportNormSheetProps.Top := pnImportNormSheetProps.Top + 1;
        Application.ProcessMessages;
        pnImportNormSheetProps.Top := pnImportNormSheetProps.Top - 1;
        Application.ProcessMessages;
      end;
  end;
  SetCaptionToStepPages;

  XPMenu.Active := false;
  XPMenu.Active := true;

  pcUpdatePrice.ActivePage := TRzTabSheet(FStepSheets[0]); //pcUpdatePrice.ActivePage := tsSelectFileName;
  DropAllSelections;

  FXLSUOM := TF_Main(GForm).FUOM;
  SelectItemByIDinComboRz(cbUOM, FXLSUOM);

  SetControls;

  //if Assigned(Fxf) then
  //  FreeAndNil(Fxf);
  //Fxf := TXLSFile.Create;
  
  FActiveSheetComponPropsInfo := nil;

  FXLSPreview.Close;

  Timer_OnExecute.Enabled := true;
  if ShowModal = mrOk then
    Result := true;

  FXLSPreview.Close;
  //if Assigned(Fxf) then
  //  FreeAndNil(Fxf);
end;

procedure TF_MasterUpdatePrice.gbNavigatorResize(Sender: TObject);
begin
  SetMiddleControlChilds(TControl(Sender), TControl(Self));
end;

procedure TF_MasterUpdatePrice.AddUpdateComponToNB(ATrgCatalog: TSCSCatalog; AComponInfo: TNodeObjectInfo);
var
  Compon: TSCSComponent;
  OldIDComponType: Integer;

  ChangedProp: Boolean;
  ChangedCompType: Boolean;
  ChangedCCE: Boolean;
  propnum: integer;
begin
  try
    // Если компонент существует и в нем определен тип компоненты, то выходим
    //if (AComponInfo.ID > 0) and (AComponInfo.IDComponType > 0) then
    //  Exit; ///// EXIT /////

    // Для нового компонента должна быть определена папка
    if (ATrgCatalog <> nil) or (AComponInfo.ID <> 0) then
    begin
      Compon := TSCSComponent.Create(GForm);
      OldIDComponType := Compon.ID_ComponentType;
      if AComponInfo.ID > 0 then
      begin
        Compon.LoadComponentByID(AComponInfo.ID, true);
        OldIDComponType := Compon.ID_ComponentType;
      end
      else
      begin
        Compon.ArticulDistributor := AComponInfo.ArtNo;
        Compon.ArticulProducer := AComponInfo.ArtNo;

        Compon.Cypher := TF_Main(GForm).DM.GenComponentNewCypher;
        Compon.GuidNB := CreateGUID;

        Compon.Price := AComponInfo.NewPriceInComponCurrency;
        Compon.Price_Calc := Compon.Price; 
      end;


      if cbColumnName.ItemIndex > 0 then
        Compon.Name := AComponInfo.NewName;
      if cbColumnIzm.ItemIndex > 0 then
        Compon.Izm := AComponInfo.Izm;

      LoadPropsToCompon(Compon, AComponInfo, @ChangedProp, @ChangedCompType, @ChangedCCE);
      if AComponInfo.ID = 0 then
      begin
        Compon.SaveComponentAsNew(true, false);
        if cbAutoAddInter.Checked then
        begin
          for propnum := 0 to Compon.Properties.Count - 1 do
            F_NormBase.ReDefineConstrInterfacesByProperty(Compon, PProperty(Compon.Properties[propnum]), True);
          Compon.SaveInterfacesByServFields;
        end;
      end
      else
      begin
        Compon.SaveComponent;
        // Если пришло свойство или тип компоненты, то сохраняем свойства/инетрфейсы и все что определилось автоматом
        if ChangedProp or ChangedCompType then
        begin
          Compon.SavePropertiesByServFields(Compon.ID); //Compon.SaveProperties(Compon.ID);
          Compon.SaveInterfacesByServFields; //Compon.SaveInterfaces(Compon.ID);
        end;

        if cbAutoAddInter.Checked then
        begin
          for propnum := 0 to Compon.Properties.Count - 1 do
            F_NormBase.ReDefineConstrInterfacesByProperty(Compon, PProperty(Compon.Properties[propnum]), True);
          Compon.SaveInterfacesByServFields;
        end;

        // Если изменения каснулись ЭКК
        if ChangedCCE then
          Compon.SaveCableCanalConnectorsByServFields;

        if ATrgCatalog <> nil then
        begin
          FReloadNBTree := true;
          F_NormBase.DM.DelCatRelByIDCompon(Compon.ID);
        end;
      end;

      if ATrgCatalog <> nil then
      begin
        F_NormBase.AppendToCatalRel(ATrgCatalog.ID, Compon.ID);
        Compon.TreeViewNode := TF_Main(GForm).MakeNodeForNewComponent(ATrgCatalog.TreeViewNode, Compon);
        ATrgCatalog.AddComponentToList(Compon);
      end;
      Compon.Free;

      Application.ProcessMessages;
    end;
  except
    on E: Exception do AddExceptionToLogExt(ClassName, 'AddUpdateComponToNB', E.Message);
  end;
end;

procedure TF_MasterUpdatePrice.AddNormResInfoToListView(const ACypher, AName, AIzm: String; AID: Integer; AListView: TRzListView);
var
  Listitem: TListItem;
begin
  Listitem := AListView.Items.Add;
  Listitem.Caption := ACypher;
  Listitem.SubItems.Add(AName);
  Listitem.SubItems.Add(AIzm);
  Listitem.Data := Pointer(AID);
end;

//procedure TF_MasterUpdatePrice.AddRelatedControlWithMenuItem(AControl: TWinControl; ATag: Integer);
//begin
//  AControl.Tag := ATag;
//  FControlsRelatedToMenuItems.Add(AControl);
//end;

// удаляет из начала нули, дефисы (даже если перед ним есть один символ)
//function TF_MasterUpdatePrice.CutBeginZeroDefisInArticle(const AArtNo: String): String;
//begin
//  Result := AArtNo;
//  if (Length(Result) > 1) and (Result[2] = '-') then
//  begin
//    delete(Result, 1, 2);
//  end;
//
//  while Length(Result) > 0 do
//  begin
//    case Result[1] of
//      '0', '-':
//        delete(Result, 1, 1);
//      else
//      begin
//        Break; //// BREAK ////
//      end;
//    end;
//  end;
//end;

procedure TF_MasterUpdatePrice.DropAllSelections;
begin
  DropSelectionForFile;
  DropSelectionForSheet;
  DropSelectionForPrices;

  FIsLoadedCurrency := false;
  ZeroMemory(@FActiveCurrency, SizeOf(TCurrency));
  ClearComboBoxRz(cbCurrency);
end;

procedure TF_MasterUpdatePrice.DropSelectionForFile;
begin
  edFileNameXls.Text := '';
  FIsOpenedXlsFile := false;
  FIsLoadedXlsFile := false;
  //FActiveTabXFSheetInfo := nil;
  FActiveSheetComponPropsInfo := nil;

  FOpenedFileName := '';
  FXLSPreview.ClearPages; //ClearXlsDataFromForm;
end;

procedure TF_MasterUpdatePrice.DropSelectionForSheet;
begin
  DropSelectionForPrices;

  FISLoadedComponents := false;
  FISLoadedResources := false;
  FISLoadedNorms := false;

  ClearNodes;
end;

procedure TF_MasterUpdatePrice.DropSelectionForPrices;
begin
  FISLoadedComponentPrices := false;
  FISLoadedResourcePrices := false;
end;

procedure TF_MasterUpdatePrice.ClearNodes;
var
  i: integer;
  Node: TFlYNode;
begin
  for i := 0 to tvComponents.Items.Count - 1 do
  begin
    Node := tvComponents.Items[i];
    if Node.Data <> nil then
      if TObject(Node.Data) is TNodeObjectInfo then
      begin
        TNodeObjectInfo(Node.Data).Free;
        Node.Data := nil;
      end;
  end;
  tvComponents.Items.Clear;
end;

procedure TF_MasterUpdatePrice.ClearStepSheetInfo;
var
  i: Integer;
  CurrPage: TRzTabSheet;
  StepSheetInfo: TStepSheetInfo;
begin
  for i := 0 to pcUpdatePrice.PageCount - 1 do
  begin
    CurrPage := pcUpdatePrice.Pages[i];
    StepSheetInfo := TStepSheetInfo(CurrPage.Tag);
    CurrPage.Tag := 0;
    FreeAndNil(StepSheetInfo);
  end;
end;

procedure TF_MasterUpdatePrice.ClearXlsDataFromForm;
begin
  while pcXFSheets.PageCount > 0 do
    pcXFSheets.Pages[0].Free;
end;

procedure TF_MasterUpdatePrice.CreateColumnsInListView(AListView: TRzListView; AColNames: TStringList; AWidthList: TIntList);
var
  i: Integer;

  procedure AddColumnToListView(const AColName: String; AWidth: Integer);
  var
    NewColumn: TListColumn;
  begin
    if AColName <> '' then
    begin
      NewColumn := AListView.Columns.Add;
      NewColumn.Caption := AColName;
      NewColumn.Width := AWidth;
    end;
  end;
begin
  AListView.ViewStyle := vsReport;
  AListView.ColumnClick := false;
  AListView.GridLines := true;
  AListView.RowSelect := true;
  AListView.ReadOnly := true;

  AListView.Columns.Clear;

  if AColNames.Count >= AWidthList.Count then
    for i := 0 to AColNames.Count - 1 do
      AddColumnToListView(AColNames[i], AWidthList[i]);
end;

procedure TF_MasterUpdatePrice.CreateColumnsInListViewFromTVColumns(AListView: TRzListView; ATree: TFlyTreeViewPro; AColIndexes: array of Integer);
var
  i: Integer;
  ColCount: Integer;

  TreeColumn: TTreeColumn;

  ColNames: TStringList;
  ColWidth: TIntList;
begin
  ColNames := TStringList.Create;
  ColWidth := TIntList.Create;

  ColCount := Length(AColIndexes);
  for i := 0 to ColCount - 1 do
  begin
    TreeColumn := ATree.Columns[AColIndexes[i]];
    if TreeColumn <> nil then
    begin
      ColNames.Add(TreeColumn.Caption);
      ColWidth.Add(TreeColumn.Width);
    end;
  end;

  CreateColumnsInListView(AListView, ColNames, ColWidth);

  FreeAndNil(ColNames);
  FreeAndNil(ColWidth);
end;

function TF_MasterUpdatePrice.CreateStepSheetInfo(ATabSheet: TRzTabSheet; APanelCaption: TRzPanel): TStepSheetInfo;
begin
  Result := TStepSheetInfo.Create;
  Result.FSheetOwner := ATabSheet;
  Result.FPanelCaption := APanelCaption;
  Result.FCaptionValue := APanelCaption.Caption;

  ATabSheet.Tag := Integer(Result);
end;

function TF_MasterUpdatePrice.GetCurrStepIndex: Integer;
begin
  Result := FStepSheets.IndexOf(pcUpdatePrice.ActivePage);
  //if Result = -1 then
  //  raise Exception.Create('Not accessible step page');
end;

function TF_MasterUpdatePrice.GetPriceInXLSUOM(APrice: Double; ANodeComponInfo: TNodeObjectInfo): Double;
begin
  Result := APrice;
  if ANodeComponInfo.IsTransformPrice then
    Result := FloatInUOM(APrice, FXLSUOM, umMetr);
end;

function TF_MasterUpdatePrice.GetPriceInNBUOM(APrice: Double; ANodeComponInfo: TNodeObjectInfo): Double;
begin
  Result := APrice;
  if ANodeComponInfo.IsTransformPrice then
    Result := FloatInUOM(APrice, umMetr, FXLSUOM);
end;

function TF_MasterUpdatePrice.GetStructLevelCombo(ALevelNum: Integer): TRZComboBox;
begin
  Result := TRzComboBox(FindComponent('cbStructLevel'+IntToStr(ALevelNum)));
end;

function TF_MasterUpdatePrice.GetStructLevelFromName(const AName, ANamePrefix: string): Integer;
var
  CharCount: Integer;
begin
  Result := -1;
  CharCount := Length(AName) - Length(ANamePrefix);
  if CharCount > 0 then
    Result := StrToIntDef(Copy(AName, Length(ANamePrefix)+1, CharCount), Result);
end;

//function TF_MasterUpdatePrice.GetRelatedControlWithMenuItemByTag(ATag: Integer): TWinControl;
//var
//  RelatedControl: TWinControl;
//  i: integer;
//begin
//  Result := nil;
//  for i := 0 to FControlsRelatedToMenuItems.Count - 1 do
//  begin
//    RelatedControl := TWinControl(FControlsRelatedToMenuItems[i]);
//    if RelatedControl.Tag = ATag then
//    begin
//      Result := RelatedControl;
//      Break; //// BREAK ////
//    end;
//  end;
//end;

procedure TF_MasterUpdatePrice.ImportNormResToBase;
var
  Node: TFlyNode;
  NodeObjInfo: TNodeObjectInfo;
  SrcObjInfo: TObjectList;
  i: Integer;

  CanAddObjToList: Boolean;
  DirName: String;

  NBResource: TNBResource;
  NBNorm: TNBNorm;
  NBSpravochnik: TSpravochnik;
begin
  try
    SrcObjInfo := TObjectList.Create(false);

    //*** Определить исходные ветви обновляемых компонент
    for i := 0 to tvComponents.Items.Count - 1 do
    begin
      Node := tvComponents.Items[i];
      if Node.StateIndex = STATE_CHECKED then
        if Node.Data <> nil then
          if TObject(Node.Data) is TNodeObjectInfo then
          begin
            NodeObjInfo := TNodeObjectInfo(Node.Data);
            CanAddObjToList := true;

            if FFormMode = fmImportResources then
              // Не добавляем в список, если тип не определен
              if GetResourceTypeName(NodeObjInfo.ResType) = '' then
                CanAddObjToList := false;

            if CanAddObjToList then
              SrcObjInfo.Add(NodeObjInfo);
          end;
    end;

    if SrcObjInfo.Count > 0 then
    begin
      BeginProgress('', SrcObjInfo.Count);
      try
        DirName := cMasterUpdatePrice_Msg6 +' "' + ExtractFileNameOnly(FXLSPreview.FileName)+'" '+DateTimeToStr(Now);
        NBSpravochnik := TF_Main(GForm).GSCSBase.NBSpravochnik;

        //*** Внести объекты в справочники
        for i := 0 to SrcObjInfo.Count - 1 do
        begin
          NodeObjInfo := TNodeObjectInfo(SrcObjInfo[i]);
          case FFormMode of
            fmImportResources:
              begin
                NBResource := TNBResource.Create(GForm);
                NBResource.Cypher := NodeObjInfo.Cypher;
                NBResource.Name := NodeObjInfo.Name;
                NBResource.Izm := NodeObjInfo.Izm;
                NBResource.Price := NodeObjInfo.NewPriceInComponCurrency;
                NBResource.RType := NodeObjInfo.ResType;
                NBSpravochnik.AddResource(NBResource);

                NBResource.Save(meMake);
                TF_Main(GForm).DM.InsertToDirTypeItemByDirTypeName(ditNBResource, DirName, NBResource.ID, @FInsertedDirTypeID);
              end;
            fmImportNorms:
              begin
                NBNorm := TNBNorm.Create(GForm);
                NBNorm.Cypher := NodeObjInfo.Cypher;
                NBNorm.Name := NodeObjInfo.Name;
                NBNorm.Izm := NodeObjInfo.Izm;
                NBSpravochnik.AddNorm(NBNorm);

                NBNorm.Save(meMake);
                TF_Main(GForm).DM.InsertToDirTypeItemByDirTypeName(ditNBNorm, DirName, NBNorm.ID, @FInsertedDirTypeID);
              end;
          end;
          StepProgress;
        end;
      finally
        EndProgress;
      end;
    end;
    FreeAndNil(SrcObjInfo);
  except
    on E: Exception do AddExceptionToLogEx('TF_MasterUpdatePrice.ImportNormResToBase', E.Message);
  end;
end;

procedure TF_MasterUpdatePrice.LoadColumnsToStrings(AStrings: TStrings; AColumnCount: Integer);
var
  i: Integer;
begin
  AStrings.Clear;
  AStrings.Add(cNoDefined);
  if AColumnCount > 0 then
  begin
    AStrings.BeginUpdate;
    try
      for i := 0 to AColumnCount - 1 do
      begin
        AStrings.Add(DecToABC(i+1));
        //AStrings.Add(DecToABC(i+1)+'  '+IntToStr(i+1)+'  '+IntToStr(ABCToDec(DecToABC(i+1))));
        //if (i+1) <> ABCToDec(DecToABC(i+1)) then
        //  EmptyProcedure;
      end;
    finally
      AStrings.EndUpdate;
    end;
  end;
end;

procedure TF_MasterUpdatePrice.LoadComponentsFromXF;
var
  ArticulNoList: TStringList;
  PriceList: TStringList;
  NewNameList: TStringList;
  CanUsePosition: Boolean;

  CurrArtNo: String;
  CurrPriceStr: String;
  CurrPrice: Double;
  CurrName: String;

  StructLevelName: String;
  StructLevelIndex: Integer;

  ComponFieldNames: TStringList;
  FNArtNo: string;
  QSelect: TpFIBQuery;
  QSelectSmart: TpFIBQuery;
  QSelSrc: TpFIBQuery;

  NewNode: TFlyNode;
  NewNodeComponInfo: TNodeObjectInfo;
  Node: TFlyNode;
  NodeComponInfo: TNodeObjectInfo;
  ptrComponCurrencyM: PObjectCurrencyRel;
  SprCurrency: TNBCurrency;
  SprComponentType: TNBComponentType;

  XLSRowInfo: TXLSRowInfo;
  XLSRowInfoList: TObjectList;

  CurrencyValue: Double;

  i, j: Integer;
  LackComponsPos: TIntList; // позиции отсутствующих компонентов в xls
  ComponPos: Integer;
  // Tolik 28/08/2019 --
  //OldTick, CurrTick: Cardinal;
  OldTick, CurrTick: DWord;
  //

  ActiveTabXFSheetInfo: TTabXFSheetInfo;
  ActiveSheetComponPropsInfo: TSheetComponPropsInfo;
  NBAllArticles: TStringList;
  StartRow: integer;
begin
  ClearNodes;
  ActiveTabXFSheetInfo := FXLSPreview.ActiveTabXFSheetInfo; //FActiveTabXFSheetInfo;
  if ActiveTabXFSheetInfo <> nil then
  begin
    ActiveSheetComponPropsInfo := TSheetComponPropsInfo(ActiveTabXFSheetInfo.RelatedObject);

    Screen.Cursor := crHourGlass;
    try
      NBAllArticles := TStringList.Create;
      ArticulNoList := TStringList.Create;
      PriceList := TStringList.Create;
      NewNameList := TStringList.Create;
      NoFindedArticles.Clear;
      FindedArticles.Clear;

      XLSRowInfoList := TObjectList.Create(true);

      BeginProgress;
      try
        //*** Составить списки с артикулами и ценами
        try
          StartRow := StrToint(EdtStartPos.Text);
        except
          StartRow := 1;
        end;
        for i := (StartRow - 1) to ActiveTabXFSheetInfo.RowCount - 1 do
        //for i := 0 to FXLSPreview.Xf.Workbook.Sheets[ActiveTabXFSheetInfo.SheetIndex].Rows.Count - 1 do
        begin
          CurrArtNo := FXLSPreview.Xf.Workbook.Sheets[ActiveTabXFSheetInfo.SheetIndex].Cells[i, ActiveSheetComponPropsInfo.ArtNoColumIndex].ValueAsString;
          if CurrArtNo <> '' then
            NBAllArticles.Add(CurrArtNo);

          CurrPriceStr := '';
          if ActiveSheetComponPropsInfo.PriceColumIndex > 0 then
            CurrPriceStr := FXLSPreview.Xf.Workbook.Sheets[ActiveTabXFSheetInfo.SheetIndex].Cells[i, ActiveSheetComponPropsInfo.PriceColumIndex].ValueAsString
          else
          begin
            CurrPriceStr := DefPrice.Text;
          end;
          CurrName := '';
          if ActiveSheetComponPropsInfo.NameColumIndex > 0 then
            CurrName := FXLSPreview.Xf.Workbook.Sheets[ActiveTabXFSheetInfo.SheetIndex].Cells[i, ActiveSheetComponPropsInfo.NameColumIndex].ValueAsString;

          CurrPrice := 0;
          CurrPriceStr := CorrectStrToFloat(CurrPriceStr);
          if CurrPriceStr <> '' then
          begin
            CanUsePosition := true;
            try
              CurrPrice := StrToFloatU(CurrPriceStr);
            except
              CanUsePosition := false;
            end;
            if (CurrArtNo <> '') and CanUsePosition then
            begin
              ArticulNoList.Add(CurrArtNo);
              PriceList.Add(CurrPriceStr);
              NewNameList.Add(CurrName);

              XLSRowInfo := TXLSRowInfo.Create;
              XLSRowInfo.FRowIndex := i;
              XLSRowInfo.FArtNo := CurrArtNo;
              XLSRowInfo.FName := CurrName;
              XLSRowInfo.FPrice := CurrPrice;
              if ActiveSheetComponPropsInfo.IzmColumIndex > 0 then
                XLSRowInfo.FIzm := FXLSPreview.Xf.Workbook.Sheets[ActiveTabXFSheetInfo.SheetIndex].Cells[i, ActiveSheetComponPropsInfo.IzmColumIndex].ValueAsString;

              // Уровни структуры
              for j := 0 to cntStructLevels - 1 do
              begin
                StructLevelName := '';
                StructLevelIndex := ActiveSheetComponPropsInfo.StructLevelsIndex[j];
                if StructLevelIndex > 0 then
                begin
                  StructLevelName := FXLSPreview.Xf.Workbook.Sheets[ActiveTabXFSheetInfo.SheetIndex].Cells[i, StructLevelIndex].ValueAsString;
                  // Если просто пробелы, то пропускаем
                  if RemoveSymbolFromStr(StructLevelName, ' ') <> '' then
                    XLSRowInfo.FCatalogs.Add(Trim(StructLevelName));
                end;
              end;

              // Подтягиваем остальные свойства
              //ActiveSheetComponPropsInfo.FMT.First;
              //while Not ActiveSheetComponPropsInfo.FMT.Eof do
              //begin
              //  PropColumnNum := ActiveSheetComponPropsInfo.FMT.FieldByName(fnColumnNum).AsInteger;
              //  if PropColumnNum > 0 then
              //  begin
              //    CellValue := FXLSPreview.Xf.Workbook.Sheets[ActiveTabXFSheetInfo.SheetIndex].Cells[i, PropColumnNum].ValueAsString;
              //    // Если просто пробелы, то пропускаем
              //    if RemoveSymbolFromStr(StructLevelName, ' ') <> '' then
              //      AddGUIDIDToStrings(CellValue, ActiveSheetComponPropsInfo.FMT.FieldByName(fnSysName).AsString, 0, XLSRowInfo.FPropValues);
              //  end;
              //  ActiveSheetComponPropsInfo.FMT.Next;
              //end;

              XLSRowInfoList.Add(XLSRowInfo);
            end;
          end;
        end;
      finally
        EndProgress;
      end;

      {OldTick := GetTickCount;
        QSelect := TF_Main(GForm).DM.Query_Select;
        SetSQLToFIBQuery(QSelect, GetSQLByParams(qtSelect, tnComponent,
          'NOT('+FNArtNo+' = '''')', ComponFieldNames, ''), true);
        CurrTick := GetTickCount - OldTick;
        while Not QSelect.Eof do
        begin
          QSelect.Next;
        end; }

      //*** определить имя поля, по которому будет осуществляться поиск
      FNArtNo := fnArticulProducer;
      if ActiveSheetComponPropsInfo.ArtNoType = antDistrib then
        FNArtNo := fnArticulDistributor;

      //*** по найденным артикулам найти компоненты
      ComponFieldNames := TStringList.Create;
      ComponFieldNames.Add(fnID);
      ComponFieldNames.Add(FNArtNo);
      ComponFieldNames.Add(fnName);
      ComponFieldNames.Add(fnPrice);
      ComponFieldNames.Add(fnIDComponentType);

      LackComponsPos := TIntList.Create;

      BeginProgress('', ArticulNoList.Count);
      try
        OldTick := GetTickCount;
        //*** Выбрать компоненты
        QSelect := TF_Main(GForm).DM.Query_Select;
        QSelectSmart := nil;
        // Если Smart сравнение артикулов
        if cbSmartCompareArtNo.Checked then
        begin
          QSelectSmart := TF_Main(GForm).DM.Query;
          SetSQLToFIBQuery(QSelectSmart, GetSQLByParams(qtSelect, tnComponent,
            'UPPER('+FNArtNo+') CONTAINING :'+FNArtNo, ComponFieldNames, ''), false);
          //''+FNArtNo+' CONTAINING :'+FNArtNo, ComponFieldNames, ''), false);
        end;
        SetSQLToFIBQuery(QSelect, GetSQLByParams(qtSelect, tnComponent,
          'UPPER('+FNArtNo+') = :'+FNArtNo, ComponFieldNames, ''), false);

        for i := 0 to XLSRowInfoList.Count - 1 do
        //for i := 0 to ArticulNoList.Count - 1 do
        begin
          XLSRowInfo := TXLSRowInfo(XLSRowInfoList[i]);

          QSelect.Close;
          QSelect.Params[0].AsString := AnsiUpperCase(ArticulNoList[i]);
          QSelect.ExecQuery;
          QSelSrc := QSelect;
          if (QSelect.RecordCount = 0) and (cbSmartCompareArtNo.Checked) then
          begin
            //QSelectSmart.Close;
            //QSelectSmart.Params[0].AsString := AnsiUpperCase(CutBeginZeroDefisInArticle('57535-2'));
            //QSelectSmart.ExecQuery;

            QSelectSmart.Close;
            QSelectSmart.Params[0].AsString := AnsiUpperCase(CutBeginZeroDefisInArticle(ArticulNoList[i]));
            QSelectSmart.ExecQuery;

            QSelSrc := QSelectSmart;
          end;

          if QSelSrc.RecordCount > 0 then
          begin
            while Not QSelSrc.Eof do
            begin
              NewNode := tvComponents.Items.Add(nil, '');
              NewNode.StateIndex := STATE_CHECKED;

              NewNodeComponInfo := TNodeObjectInfo.Create(NewNode);

              NewNodeComponInfo.ID := QSelSrc.FN(fnID).AsInteger;
              NewNodeComponInfo.ArtNo := QSelSrc.FN(FNArtNo).AsString; //ArticulNoList[i];
              NewNodeComponInfo.Name := QSelSrc.FN(fnName).AsString;
              NewNodeComponInfo.CurrPrice := QSelSrc.FN(fnPrice).AsFloat;
              NewNodeComponInfo.IsTransformPrice := false;
              SprComponentType := TF_Main(GForm).GSCSBase.NBSpravochnik.GetComponentTypeObjByID(QSelSrc.FN(fnIDComponentType).AsInteger);
              if SprComponentType <> nil then
                NewNodeComponInfo.IsTransformPrice := CheckPriceTransformToUOMByCompType(@SprComponentType.ComponentType.SysName);
              NewNodeComponInfo.NewPriceInXFCurrency := StrToFloatU(PriceList[i]);
              NewNodeComponInfo.NewName := NewNameList[i];
              if XLSRowInfo.FIzm <> '' then
                NewNodeComponInfo.Izm := XLSRowInfo.FIzm;
              NewNodeComponInfo.IDComponType := QSelSrc.FN(fnIDComponentType).AsInteger;

              NewNodeComponInfo.FCatalogs.Assign(XLSRowInfo.FCatalogs);
              NewNodeComponInfo.FRowIndex := XLSRowInfo.FRowIndex;

              NewNode.Text := NewNodeComponInfo.ArtNo;
              NewNode.Data := NewNodeComponInfo;

              NewNode.Cells[ciArtNo] := NewNodeComponInfo.ArtNo;
              NewNode.Cells[ciName] := NewNodeComponInfo.Name;

              CurrencyValue := GetPriceInXLSUOM(NewNodeComponInfo.CurrPrice, NewNodeComponInfo);
              NewNode.Cells[ciCurrPrice] := FloatToStr(RoundCP(CurrencyValue)) +' '+ NewNodeComponInfo.CurrencyM.NameBrief;
              if cbColumnName.ItemIndex > 0 then //if cbUpdateNames.Checked then
                NewNode.Cells[ciNewName] := NewNodeComponInfo.NewName;

              FindedArticles.Add(ArticulNoList[i]);

              QSelSrc.Next;
            end;
          end
          else
          begin
            CurrPriceStr := PriceList[i];
            //if (CurrPriceStr <> '0') and (CurrPriceStr <> '') then
            if ((CurrPriceStr <> '')  and (cbColumnPrice.ItemIndex <> 0)) or (cbColumnPrice.ItemIndex = 0) then
              LackComponsPos.Add(i);
            NoFindedArticles.Add(ArticulNoList[i]);
          end;
          StepProgress;
        end;

        // Если нету в базе, то вносим как новый
        if cbAddLackCompons.Checked then
        begin
          for i := 0 to LackComponsPos.Count - 1 do
          begin
            ComponPos := LackComponsPos[i];
            XLSRowInfo := TXLSRowInfo(XLSRowInfoList[ComponPos]);

            NewNode := tvComponents.Items.Add(nil, '');
            NewNode.StateIndex := STATE_CHECKED;

            NewNodeComponInfo := TNodeObjectInfo.Create(NewNode);

            NewNodeComponInfo.ID := 0;
            NewNodeComponInfo.ArtNo := AnsiUpperCase(ArticulNoList[ComponPos]);
            NewNodeComponInfo.Name := NewNameList[ComponPos];
            NewNodeComponInfo.CurrPrice := 0;
            NewNodeComponInfo.IsTransformPrice := false;
            NewNodeComponInfo.NewPriceInXFCurrency := StrToFloatU(PriceList[ComponPos]);
            NewNodeComponInfo.NewPriceInComponCurrency := NewNodeComponInfo.NewPriceInXFCurrency;
            NewNodeComponInfo.NewName := NewNameList[ComponPos];
            if XLSRowInfo.FIzm <> '' then
              NewNodeComponInfo.Izm := XLSRowInfo.FIzm;
            NewNodeComponInfo.FCatalogs.Assign(XLSRowInfo.FCatalogs);

            NewNodeComponInfo.FRowIndex := XLSRowInfo.FRowIndex;

            NewNode.Text := NewNodeComponInfo.ArtNo;
            NewNode.Data := NewNodeComponInfo;

            NewNode.Cells[ciArtNo] := NewNodeComponInfo.ArtNo;
            NewNode.Cells[ciName] := NewNodeComponInfo.Name;

            CurrencyValue := GetPriceInXLSUOM(NewNodeComponInfo.CurrPrice, NewNodeComponInfo);
            NewNode.Cells[ciCurrPrice] := FloatToStr(RoundCP(CurrencyValue)) +' '+ NewNodeComponInfo.CurrencyM.NameBrief;
            if cbColumnName.ItemIndex > 0 then //if cbUpdateNames.Checked then
              NewNode.Cells[ciNewName] := NewNodeComponInfo.NewName;

          end;
        end;

        CurrTick := GetTickCount - OldTick;
        CurrTick := GetTickCount - OldTick;

        //*** Определить валюту компонент
        for i := 0 to tvComponents.Items.Count - 1 do
        begin
          Node := tvComponents.Items[i];
          NodeComponInfo := TNodeObjectInfo(Node.Data);
          if (NodeComponInfo <> nil) then
          begin
            if NodeComponInfo.ID > 0 then
            begin
              ptrComponCurrencyM := TF_Main(GForm).DM.GetComponCurrencyByMainFldFromListOrQuery(NodeComponInfo.ID, ctMain, nil);
              if ptrComponCurrencyM <> nil then
              begin
                SprCurrency := TF_Main(GForm).GSCSBase.NBSpravochnik.GetCurrencyByGUID(ptrComponCurrencyM.Data.GUID);
                NodeComponInfo.CurrencyM := ptrComponCurrencyM.Data;
                if SprCurrency <> nil then
                  NodeComponInfo.CurrencyM := SprCurrency.Data;
                FreeMem(ptrComponCurrencyM);

                CurrencyValue := GetPriceInXLSUOM(NodeComponInfo.CurrPrice, NodeComponInfo);
                Node.Cells[ciCurrPrice] := FloatToStr(RoundCP(CurrencyValue)) + ' '+ NodeComponInfo.CurrencyM.NameBrief;
              end;
            end
            else
            begin
              NodeComponInfo.CurrencyM := FActiveCurrency; 
            end;
          end;
        end;
      finally
        EndProgress;
      end;

      //fsComponCountExists.Caption := IntToStr(ArticulNoList.Count - LackComponsPos.Count);
      fsComponCountExists.Caption := IntToStr(FindedArticles.Count);
      fsComponCountLack.Caption := IntToStr(LackComponsPos.Count);

      FreeAndNil(ComponFieldNames);

      FreeAndNil(LackComponsPos);

      FreeAndNil(XLSRowInfoList);
      FreeAndNil(ArticulNoList);
      FreeAndNil(PriceList);
      FreeAndNil(NewNameList);
      FreeAndNil(NBAllArticles);
      //FreeAndNil(FindedArticles);
      //FreeAndNil(NoFindedArticles);
    finally
      Screen.Cursor := crDefault;
    end;
    FISLoadedComponents := true;
  end;
end;

procedure TF_MasterUpdatePrice.LoadComponPricesFromXF;
var
  ptrComponCurrencyXF: PObjectCurrencyRel;
  Node: TFlyNode;
  NodeComponInfo: TNodeObjectInfo;
  i: Integer;

  CurrencyValue: Double;
  ptrComponCurrencyM: PObjectCurrencyRel;
  SprCurrency: TNBCurrency;
begin
  for i := 0 to tvComponents.Items.Count - 1 do
  begin
    Node := tvComponents.Items[i];
    NodeComponInfo := TNodeObjectInfo(Node.Data);
    if NodeComponInfo <> nil then
    begin
      // Текущая цена компоненты
      ptrComponCurrencyM := TF_Main(GForm).DM.GetComponCurrencyByMainFldFromListOrQuery(NodeComponInfo.ID, ctMain, nil);
      if ptrComponCurrencyM <> nil then
      begin
        SprCurrency := TF_Main(GForm).GSCSBase.NBSpravochnik.GetCurrencyByGUID(ptrComponCurrencyM.Data.GUID);
        NodeComponInfo.CurrencyM := ptrComponCurrencyM.Data;
        if SprCurrency <> nil then
          NodeComponInfo.CurrencyM := SprCurrency.Data;
        FreeMem(ptrComponCurrencyM);

        CurrencyValue := GetPriceInXLSUOM(NodeComponInfo.CurrPrice, NodeComponInfo);
        Node.Cells[ciCurrPrice] := FloatToStr(RoundCP(CurrencyValue)) + ' '+ NodeComponInfo.CurrencyM.NameBrief;
      end;

      // Новая цена из Excel
      Node.Cells[ciNewPriceInXFCurrency] := FloatToStr(RoundCP(NodeComponInfo.NewPriceInXFCurrency)) + ' '+
        FActiveCurrency.NameBrief;
      Node.Cells[ciNewPriceInComponCurrency] := '?';
      NodeComponInfo.NewPriceInComponCurrency := 0;

      if NodeComponInfo.CurrencyM.ID = FActiveCurrency.ID then
      begin
        NodeComponInfo.CurrencyXF := NodeComponInfo.CurrencyM;
        NodeComponInfo.NewPriceInComponCurrency := NodeComponInfo.NewPriceInXFCurrency;
      end
      else
      begin
        ptrComponCurrencyXF := TF_Main(GForm).DM.GetComponCurrencyByCurrencyID(NodeComponInfo.ID, FActiveCurrency.ID);
        if ptrComponCurrencyXF <> nil then
        begin
          NodeComponInfo.CurrencyXF := ptrComponCurrencyXF.Data;
          NodeComponInfo.NewPriceInComponCurrency := GetPriceAfterChangeCurrency(NodeComponInfo.NewPriceInXFCurrency,
                NodeComponInfo.CurrencyXF, NodeComponInfo.CurrencyM);
          FreeMem(ptrComponCurrencyXF);
        end
        else
        //*** Если не найдена валюта
          Node.StateIndex := STATE_UNCHECKED;
      end;
      
      if NodeComponInfo.NewPriceInComponCurrency <> 0 then
        Node.Cells[ciNewPriceInComponCurrency] := FloatToStr(RoundCP(NodeComponInfo.NewPriceInComponCurrency))+ ' '+
            NodeComponInfo.CurrencyM.NameBrief;
    end;
  end;
  FISLoadedComponentPrices := true;
end;

procedure TF_MasterUpdatePrice.LoadCurrencies(AGUIDToSelect: String);
begin
  cbCurrency.OnChange := nil;
  TF_Main(GForm).GSCSBase.NBSpravochnik.LoadCurrenciesToStrings(cbCurrency.Items, true);
  cbCurrency.OnChange := cbCurrencyChange;

  if AGUIDToSelect <> '' then
    SelectItemByGUIDinComboRz(cbCurrency, AGUIDToSelect);

  FIsLoadedCurrency := true;
end;

procedure TF_MasterUpdatePrice.LoadNormsFromXF;
var
  CurrCypher: String;
  CurrName: String;
  CurrIzm: String;

  QSelect: TpFIBQuery;

  NewNode: TFlyNode;
  NewNodeResourceInfo: TNodeObjectInfo;
  Node: TFlyNode;

  i: Integer;
  // Tolik 28/08/2019 --
  //OldTick, CurrTick: Cardinal;
  OldTick, CurrTick: DWord;
  //

  ActiveTabXFSheetInfo: TTabXFSheetInfo;
  ActiveSheetComponPropsInfo: TSheetComponPropsInfo;
begin
  ClearNodes;
  ActiveTabXFSheetInfo := FXLSPreview.ActiveTabXFSheetInfo; //FActiveTabXFSheetInfo;
  if ActiveTabXFSheetInfo <> nil then
  begin
    ActiveSheetComponPropsInfo := TSheetComponPropsInfo(ActiveTabXFSheetInfo.RelatedObject);

    Screen.Cursor := crHourGlass;
    try
      tvComponents.OnStateChanging := nil;
      BeginProgress;
      try
        lvExistsObjects.Clear;

        //*** Скрипт проверки существования ресурса по шифру
        QSelect := TF_Main(GForm).DM.Query_Select;
        SetSQLToFIBQuery(QSelect, GetSQLByParams(qtSelect, tnNBNorms,
          'UPPER('+fnCypher+') = :'+fnCypher, nil, fnID), false);

        //*** Вкидываем в дерево данные из Excel
        for i := 0 to FXLSPreview.ActiveTabXFSheetInfo.RowCount - 1 do
        begin
          CurrCypher := FXLSPreview.Xf.Workbook.Sheets[ActiveTabXFSheetInfo.SheetIndex].Cells[i, ActiveSheetComponPropsInfo.NormResCypherColumIndex].ValueAsString;
          CurrName := FXLSPreview.Xf.Workbook.Sheets[ActiveTabXFSheetInfo.SheetIndex].Cells[i, ActiveSheetComponPropsInfo.NormResNameColumIndex].ValueAsString;
          CurrIzm := FXLSPreview.Xf.Workbook.Sheets[ActiveTabXFSheetInfo.SheetIndex].Cells[i, ActiveSheetComponPropsInfo.NormResIzmColumIndex].ValueAsString;

          if CurrCypher <> '' then
          begin
            QSelect.Close;
            QSelect.Params[0].AsString := AnsiUpperCase(CurrCypher);
            QSelect.ExecQuery;
            if QSelect.Eof then
            begin
              NewNode := tvComponents.Items.Add(nil, '');
              NewNode.StateIndex := STATE_CHECKED;

              NewNodeResourceInfo := TNodeObjectInfo.Create(NewNode);

              NewNodeResourceInfo.ID := 0;
              NewNodeResourceInfo.Cypher := CurrCypher;
              NewNodeResourceInfo.Name := CurrName;
              NewNodeResourceInfo.Izm := CurrIzm;

              NewNode.Text := NewNodeResourceInfo.Cypher;
              NewNode.Data := NewNodeResourceInfo;

              NewNode.Cells[ciCypher] := NewNodeResourceInfo.Cypher;
              NewNode.Cells[ciName] := NewNodeResourceInfo.Name;
              NewNode.Cells[ciIzm] := NewNodeResourceInfo.Izm;
            end
            else
              AddNormResInfoToListView(CurrCypher, CurrName, CurrIzm, QSelect.Fields[0].AsInteger, lvExistsObjects);
          end;
          StepProgress;
        end;
      finally
        EndProgress;
      end;
      tvComponents.OnStateChanging := tvComponentsStateChanging;
    finally
      Screen.Cursor := crDefault;
    end;
    FISLoadedNorms := true;
  end;
end;

procedure TF_MasterUpdatePrice.LoadPropsToCompon(AComponent: TSCSComponent; AComponInfo: TNodeObjectInfo; AChangedProp, AChangedCompType, AChangedCCE: PBoolean);
var
  AllowSetComponAsLite: Boolean;
  ActiveTabXFSheetInfo: TTabXFSheetInfo;
  ActiveSheetComponPropsInfo: TSheetComponPropsInfo;
  PropColumnNum: Integer;
  CellValue: String;
  CellValueFloat: Double;
  MTPropSysName: String;
  PrefixLen: Integer;
  PropSysName: String;

  PropValues: TStringList;

  ChangedProp: Boolean;
  ChangedCompType: Boolean;

  NBCompType: TNBComponentType;
  NBProperty: TNBProperty;
  TmpPos: Integer;
  ptrProperty: PProperty;
  ptrSuppliesKind: PSuppliesKind;
  SuppliesKindName: String;
  UOMStr: String;
  NBObjectIcon: TNBObjectIcon;
  NBInterf: TNBInterface;
  Interf, Interf1, Interf2: TSCSInterface;
  PortInterfRel: PPortInterfRel;
  GenLastInterfID: Integer;
  IsPriceForSuppliesKind: Boolean;

  i, j: Integer;
  TempDescr: TStringList;
  TempExistDescr: TStringList;
  Stream: TFileStream;

  // Определяет сечение по диаметру
  procedure DefineSection(const ADiametrProp, ASectionProp: String);
  var
    CellValue: String;
    CellValueFloat: Double;
  begin
    CellValue := GetNameFromStringsByGUID(tnCompPropRelation+'.'+ADiametrProp, PropValues);
    if (CellValue <> '') and (GetNameFromStringsByGUID(tnCompPropRelation+'.'+ASectionProp, PropValues) = '') then
    begin
      CellValue := CorrectStrToFloat(CellValue);
      CellValueFloat := StrToFloatDef(CellValue, 0);
      if CellValueFloat <> 0 then
      begin
        // Определяем сечение по диаметру - тоесть площадь круга = pi*R^2
        CellValueFloat := pi * SQR(CellValueFloat / 2);
        AddGUIDIDToStrings(FloatToStr(CellValueFloat), tnCompPropRelation+'.'+ASectionProp, 0, PropValues);
      end;
    end;
  end;

  procedure DefineCCEByArticul(const AArticul: String);
  var
    i: integer;
    IDCCE: Integer;
    ptrCableCanalConnector: PCableCanalConnector;
  begin
    // Ищем компонент по артикулу
    IDCCE := TF_Main(GForm).FNormBase.DM.GetIntFromTable(tnComponent, fnID, fnArticulProducer, AArticul, qmPhisical);
    if IDCCE <> 0 then
    begin
      // Ищим ЭКК
      ptrCableCanalConnector := AComponent.GetCCEByIDConnector(IDCCE);
      if ptrCableCanalConnector = nil then
      begin
        ptrCableCanalConnector := AComponent.AddCCEToList(IDCCE, -1);
        ptrCableCanalConnector.IsNew := true;
        if AChangedCCE <> nil then
          AChangedCCE^ := true;
      end;
    end;
  end;

  function GetCellValueByProp(const APropSysName: String): String;
  var
    idx: Integer;
  begin
    Result := '';
    idx := IndexOfGUIDInStrings(APropSysName, PropValues);
    if idx <> -1 then
      Result := PropValues[idx];
  end;

begin
  try
    ActiveTabXFSheetInfo := FXLSPreview.ActiveTabXFSheetInfo;
    ActiveSheetComponPropsInfo := TSheetComponPropsInfo(ActiveTabXFSheetInfo.RelatedObject);
    ActiveSheetComponPropsInfo.FMT.First;

    AllowSetComponAsLite := true;
    ChangedProp := false;
    ChangedCompType := false;
    if AChangedCCE <> nil then
      AChangedCCE^ := false;
    PropValues := nil;
    GenLastInterfID := 0;

    PrefixLen := Length(tnCompPropRelation+'.');
    while Not ActiveSheetComponPropsInfo.FMT.Eof do
    begin
      PropColumnNum := ActiveSheetComponPropsInfo.FMT.FieldByName(fnColumnNum).AsInteger;
      if PropColumnNum > 0 then
      begin
        CellValue := FXLSPreview.Xf.Workbook.Sheets[ActiveTabXFSheetInfo.SheetIndex].Cells[AComponInfo.FRowIndex, PropColumnNum-1].ValueAsString;
        // Если просто пробелы, то пропускаем
        if RemoveSymbolFromStr(CellValue, ' ') <> '' then
        begin
          MTPropSysName := ActiveSheetComponPropsInfo.FMT.FieldByName(fnSysName).AsString;
          if PropValues = nil then
            PropValues := TStringList.Create;
          AddGUIDIDToStrings(CellValue, MTPropSysName, 0, PropValues);

          //// Если свойство из справочника
  //        TmpPos := Pos(tnCompPropRelation+'.', MTPropSysName);
  //        if TmpPos = 1 then
  //        begin
  //          PropSysName := Copy(MTPropSysName, PrefixLen+1, Length(MTPropSysName) - PrefixLen);
  //          // Определяем справочное свойство по SYSNAME
  //          NBProperty := F_NormBase.GSCSBase.NBSpravochnik.GetPropertyBySysName(PropSysName);
  //          // Определяем справочное свойство по наименованию
  //          if NBProperty = nil then
  //            NBProperty := F_NormBase.GSCSBase.NBSpravochnik.GetPropertyByName(PropSysName);
  //          if NBProperty <> nil then
  //          begin
  //            // Если нету на компоненте свойства, то определяем его
  //            if Not AComponent.AssignedPropertyBySysName(PropSysName) then
  //            begin
  //              ptrProperty := AComponent.GetPropertyAsNew;
  //              NBProperty.AssignToPProperty(ptrProperty);
  //            end;
  //            AComponent.SetPropertyValueAsString(PropSysName, GetPropStrValueByDisplay(CellValue, PropSysName, NBProperty.PropertyData.IDDataType, TF_Main(AComponent.ActiveForm).FUOM));
  //            ChangedProp := true;
  //          end;
  //        end
  //        else
  //        begin
  //          // Если тип компонента
  //          if MTPropSysName = fnComponentType then
  //          begin
  //            if AComponent.ID_ComponentType = 0 then
  //            begin
  //              // Определяем справочный тип компонента по GUID
  //              NBCompType := F_NormBase.GSCSBase.NBSpravochnik.GetComponentTypeByGUID(CellValue);
  //
  //              // Определяем справочный тип компонента SYS_NAME
  //              //if NBCompType = nil then
  //              //begin
  //              //  PropGUID := '';
  //              //  ctsnCable	{A1E3766B-4306-4825-AAA8-7385321233EC}
  //              //  ctsnSocket	{133728E3-D381-4B88-882A-70D051475D4C}
  //              //  ctsnPatchPanel	{ED263346-F61C-4A69-98F4-5094287F39EF}
  //              //  ctsnPatchCord	{9527496D-3FAE-4F0F-A44F-DEDC51BBC8B5}
  //              //  ctsnAdapter	{04EE3BAB-E345-47E1-B53A-F1AB9C73B939}
  //              //  ctsnModule	{DCB31978-3D85-4DB9-B9FC-8E0407B09A37}
  //              //  ctsnBox	{1C134A31-B805-4F8B-B361-03587D1E5CE0}
  //              //  ctsnOFCable	{6C5D9FFE-8F99-49A0-BDB6-F59A778B9C03}
  //              //  ctsnFrame	{DD4EFEEA-0263-40E3-AFBE-795B032D2CAE}
  //              //  ctsnOther	{B5D47C23-0DD7-4C27-8878-CE02D2FCAB97}
  //              //  ctsnAccessory	{0B8B2B89-9259-4688-9553-C85FED94D228}
  //              //  ctsn19InchPanel	{DCAD62C4-B099-4E1F-B984-7C87F5AE90D0}
  //              //  ctsnOFConnector	{7427141E-9C4E-4864-91B3-D26AC17B5C0D}
  //              //  ctsnOFModule	{9F29B8C0-CC1F-4F85-BD53-9F05FA0BD87E}
  //              //
  //              //  NBCompType := F_NormBase.GSCSBase.NBSpravochnik.GetComponentTypeObjBySysName('');
  //              //end;
  //
  //              // Определяем справочный тип компонента наименованию
  //              if NBCompType = nil then
  //                NBCompType := F_NormBase.GSCSBase.NBSpravochnik.GetComponentTypeByName(CellValue);
  //
  //              if NBCompType <> nil then
  //              begin
  //                AComponent.ID_ComponentType := NBCompType.ComponentType.ID;
  //                AComponent.LoadComponentType;
  //                AComponent.LoadPropertyesFromComponentType;
  //
  //                ChangedCompType := true;
  //              end;
  //            end;
  //          end
  //          else if MTPropSysName = AnsiUpperCase(fnSign) then
  //          begin
  //            AComponent.NameShort := CellValue;
  //          end;
  //        end;
  //        //AddGUIDIDToStrings(CellValue, ActiveSheetComponPropsInfo.FMT.FieldByName(fnSysName).AsString, 0, XLSRowInfo.FPropValues);
        end;
      end;
      ActiveSheetComponPropsInfo.FMT.Next;
    end;

    if PropValues <> nil then
    begin
      if PropValues.Count > 0 then
      begin
        // Если есть свойство внешний диаметр, то ищем сечение если такого нету
        DefineSection(pnOutDiametr, pnOutSection);
        DefineSection(pnInDiametr, pnInSection);
      end;

      for i := 0 to PropValues.Count - 1 do
      begin
        CellValue := PropValues[i];
        MTPropSysName := GetGUIDFromStrings(PropValues, i);
        // Если свойство из справочника
        TmpPos := Pos(tnCompPropRelation+'.', MTPropSysName);
        if TmpPos = 1 then
        begin
          PropSysName := Copy(MTPropSysName, PrefixLen+1, Length(MTPropSysName) - PrefixLen);
          // Определяем справочное свойство по SYSNAME
          NBProperty := F_NormBase.GSCSBase.NBSpravochnik.GetPropertyBySysName(PropSysName);
          // Определяем справочное свойство по наименованию
          if NBProperty = nil then
            NBProperty := F_NormBase.GSCSBase.NBSpravochnik.GetPropertyByName(PropSysName);
          if NBProperty <> nil then
          begin
            // Если нету на компоненте свойства, то определяем его
            ptrProperty := AComponent.GetPropertyBySysName(PropSysName);
            if ptrProperty = nil then
            //if Not AComponent.AssignedPropertyBySysName(PropSysName) then
            begin
              ptrProperty := AComponent.GetPropertyAsNew;
              ptrProperty.IsNew := true;
              NBProperty.AssignToPProperty(ptrProperty);
            end
            else
            begin
              ptrProperty.IsModified := true;
            end;
            // Если Float, то меняем точку на запятую
            if NBProperty.PropertyData.IDDataType = dtFloat then
              CellValue := CorrectStrToFloat(CellValue);
            AComponent.SetPropertyValueAsString(PropSysName, GetPropStrValueByDisplay(CellValue, PropSysName, NBProperty.PropertyData.IDDataType, TF_Main(AComponent.ActiveForm).FUOM));
            ChangedProp := true;
          end;
        end
        else
        begin
          // Если тип компонента
          if MTPropSysName = fnComponentType then
          begin
            if AComponent.ID_ComponentType = 0 then
            begin
              // Определяем справочный тип компонента по GUID
              NBCompType := F_NormBase.GSCSBase.NBSpravochnik.GetComponentTypeByGUID(CellValue);

              // Определяем справочный тип компонента наименованию
              if NBCompType = nil then
                NBCompType := F_NormBase.GSCSBase.NBSpravochnik.GetComponentTypeByName(CellValue);

              if NBCompType <> nil then
              begin
                AComponent.ID_ComponentType := NBCompType.ComponentType.ID;
                AComponent.LoadComponentType;
                AComponent.LoadPropertyesFromComponentType;
                // Свойства как новые
                for j := 0 to AComponent.Properties.Count - 1 do
                begin
                  ptrProperty := AComponent.Properties[j];
                  ptrProperty.IsNew := true;
                end;

                AComponent.IsLine := GetIsLineByComponType(NBCompType.ComponentType);

                ChangedCompType := true;
              end;
            end;
          end
          // Обозначение
          else if MTPropSysName = AnsiUpperCase(fnSign) then
          begin
            AComponent.NameShort := CellValue;
          end
          // Описание
          else if MTPropSysName = AnsiUpperCase(fnDescription) then
          begin
            if Trim(CellValue) <> '' then
            begin
              TempDescr := TStringList.Create;
              TempDescr.Text := Trim(CellValue);
              if aComponent.Description = nil then
                aComponent.Description := TMemoryStream.Create;
              if cbAddToDescr.Checked then
              begin
                TempExistDescr := TStringList.Create;
                aComponent.Description.Position := 0;
                TempExistDescr.LoadFromStream(aComponent.Description);
                aComponent.Description.Position := 0;
                if Pos(Trim(CellValue), TempExistDescr.Text) <= 0 then
                begin
                  if Trim(TempExistDescr.Text) <> '' then
                    TempDescr.Text := Trim(CellValue) + #13#10 + Trim(TempExistDescr.Text);
                  aComponent.Description.Clear;
                  aComponent.Description.Position := 0;
                  TempDescr.SaveToStream(aComponent.Description);
                end;
                TempDescr.Free;
                TempExistDescr.Free;
              end
              else
              begin
                aComponent.Description.Clear;
                aComponent.Description.Position := 0;
                TempDescr.SaveToStream(aComponent.Description);
                TempDescr.Free;
              end;
            end;
          end
          // Картинка
          else if AnsiUpperCase(MTPropSysName) = 'IMAGE' then
          begin
            if aComponent.Picture = nil then
              aComponent.Picture := TMemoryStream.Create;
            aComponent.Picture.Clear;
            aComponent.Picture.Position;
            try
              if FileExists(Trim(CellValue)) then
              begin
                Stream := TFileStream.Create(Trim(CellValue), fmOpenReadWrite);
                Stream.Position := 0;
                aComponent.Picture.Position := 0;
                aComponent.Picture.CopyFrom(Stream, 0);
                aComponent.Picture.Position := 0;
                FreeAndNil(Stream);
              end;
            except
              on E: Exception do
                ShowMessage(cAddComponent_Msg5);
            end;
          end
          // Ед. изм.
          else if MTPropSysName = AnsiUpperCase(fnUOM) then
          begin
            AComponent.Izm := CellValue;
          end
          // Количество единиц в поставке
          else if MTPropSysName = fnSuppliesKindUnitKolvo then
          begin
            CellValue := CorrectStrToFloat(CellValue);
            CellValueFloat := StrToFloatDef(CellValue, 0);
            if CellValueFloat > 0 then
            begin
              // Наименование вида поставки
              SuppliesKindName := GetNameFromStringsByGUID(fnSuppliesKindName, PropValues);
              // Ед.изм.
              UOMStr := GetNameFromStringsByGUID(fnUOM, PropValues);
              if UOMStr = '' then
                UOMStr := AComponent.Izm;
              if FAllSuppliesKinds = nil then
                FAllSuppliesKinds := F_NormBase.DM.GetAllSuppliesKinds;
              ptrSuppliesKind := GetSuppliesKindByIzmAndKolvo(SuppliesKindName, UOMStr, CellValueFloat, FAllSuppliesKinds);
              // Поставка не найдена, создать ее
              if ptrSuppliesKind = nil then
              begin
                GetZeroMem(ptrSuppliesKind, SizeOf(TSuppliesKind));
                ptrSuppliesKind.Izm := UOMStr;
                ptrSuppliesKind.UnitKolvo := CellValueFloat;
                ptrSuppliesKind.Name := SuppliesKindName;
                ptrSuppliesKind.NameTradUOM := ptrSuppliesKind.Name;
                ptrSuppliesKind.IzmTradUOM := ptrSuppliesKind.Izm;
                ptrSuppliesKind.UnitKolvoTradUOM := ptrSuppliesKind.UnitKolvo;
                F_NormBase.DM.InsertSuppliesKindToTopDirType(ptrSuppliesKind);
                FAllSuppliesKinds.Add(ptrSuppliesKind);
              end;
              if ptrSuppliesKind <> nil then
              begin
                AComponent.IDSuppliesKind := ptrSuppliesKind.ID;
                //23.11.2011 AComponent.PriceSupply := RoundCP(AComponent.Price * ptrSuppliesKind.UnitKolvo);
                // Определяем цена указана за поставки ли.
                IsPriceForSuppliesKind := GetCellValueByProp(fnIsPriceForSuppliesKind) = '1';
                if IsPriceForSuppliesKind then
                begin
                  AComponent.PriceSupply := AComponent.Price;
                  AComponent.Price := AComponent.PriceSupply / ptrSuppliesKind.UnitKolvo;
                end
                else
                  AComponent.PriceSupply := RoundCP(AComponent.Price * ptrSuppliesKind.UnitKolvo);
              end;
            end;
          end
          // УГО
          else if (MTPropSysName = AnsiUpperCase(fnObjectIcon)) or (MTPropSysName = AnsiUpperCase(fnObjectIconDesign)) then
          begin
            NBObjectIcon := F_NormBase.GSCSBase.NBSpravochnik.GetObjectIconByGUID(CellValue); //GetObjectIconByGUIDFromList(CellValue);
            if NBObjectIcon = nil then
              NBObjectIcon := F_NormBase.GSCSBase.NBSpravochnik.GetObjectIconByNameFromList(CellValue);
            if NBObjectIcon <> nil then
            begin
              if MTPropSysName = AnsiUpperCase(fnObjectIcon) then
                AComponent.IDObjectIcon := NBObjectIcon.ID
              else if MTPropSysName = AnsiUpperCase(fnObjectIconDesign) then
                AComponent.IDSymbol := NBObjectIcon.ID;
            end;
          end
          else
          begin
            // Если эл. каб канала
            if Pos('CE_', MTPropSysName) = 1 then
            begin
              DefineCCEByArticul(CellValue);
            end
            // Если интерфейс //22.11.2011
            else if Pos(fnInterf, MTPropSysName) = 1 then
            begin
              NBInterf := F_NormBase.GSCSBase.NBSpravochnik.GetInterfaceByGUID(CellValue);
              if NBInterf = nil then
                NBInterf := F_NormBase.GSCSBase.NBSpravochnik.GetInterfaceByName(CellValue);
              if NBInterf <> nil then
              begin
                if GenLastInterfID = 0 then
                  GenLastInterfID := GetLastInterfRelID(TF_Main(AComponent.ActiveForm).GDBMode);
                GenLastInterfID := GenLastInterfID + 1;
                Interf := AComponent.GetInterfaceAsNew;
                Interf.IsNew := true;
                Interf.ID := GenLastInterfID;
                Interf.TypeI := itFunctional;
                Interf.Kind := ikSplit;
                Interf.Gender := gtMale;
                Interf.Multiple := biFalse;
                Interf.IsBusy := biFalse;
                Interf.Kolvo := 1;
                Interf.Color := clWhite;
                Interf.AssignFromSpr(NBInterf);

                if AComponent.Interfaces.Count = 2 then
                begin
                  // Если патч-корд и есть еще один интерфейс,то связываем их
                  if AComponent.IsCrossComponent then
                  begin
                    Interf1 := AComponent.Interfaces[0];
                    Interf2 := Interf;
                  end
                  // Или если оптоволоконный соединитель типа пигтейла
                  else if AComponent.ComponentType.SysName = ctsnOFConnector then
                  begin
                    Interf1 := Interf;
                    Interf2 := AComponent.Interfaces[0];
                  end;

                  if (Interf1 <> nil) and (Interf2 <> nil) then
                  begin
                    GetZeroMem(PortInterfRel, SizeOf(TPortInterfRel));
                    PortInterfRel.ID := 0;
                    PortInterfRel.IsNew := true;
                    PortInterfRel.RelType := rtInterfInternalConn;
                    PortInterfRel.IDPort := Interf1.ID;
                    PortInterfRel.IDInterfRel := Interf2.ID;
                    PortInterfRel.UnitInterfKolvo := 1;

                    Interf1.PortInterfRels.Add(PortInterfRel);
                    Interf1.DefineInternalRelations;

                    AllowSetComponAsLite := false;
                  end;
                end;
              end;
            end;
          end;
        end;
      end;
    end;

    //if NBCompType <> nil then
    //  if (NBCompType.ComponentType.SysName = ctsn19InchPanel) or (NBCompType.ComponentType.SysName = ctsnPatchPanel) then
    //    if Not AComponent.AssignedPropertyBySysName(pnPortWireCount) then
    //    begin
    //      EmptyProcedure;
    //    end;

    if AllowSetComponAsLite then
      if ChangedProp or ChangedCompType then
        SetComponAsLite(AComponent);

    if AChangedProp <> nil then
      AChangedProp^ := ChangedProp;
    if AChangedCompType <> nil then
      AChangedCompType^ := ChangedCompType;

    if PropValues <> nil then
    begin
      RemoveGUIDIDFromStrings(PropValues, true);
      PropValues.Free;
    end;
  except
    on E: Exception do AddExceptionToLogExt(ClassName, 'LoadPropsToCompon', E.Message);
  end;
end;

procedure TF_MasterUpdatePrice.LoadResourcesFromXF;
var
  CanUsePosition: Boolean;

  CurrCypher: String;
  CurrPriceStr: String;
  CurrPrice: Double;
  CurrName: String;
  CurrIzm: String;
  CurrResTypeStr: string;
  CurrResType: Integer;

  QSelect: TpFIBQuery;

  NewNode: TFlyNode;
  NewNodeResourceInfo: TNodeObjectInfo;
  Node: TFlyNode;

  i: Integer;
  // Tolik 28/08/2019 --
  //OldTick, CurrTick: Cardinal;
  OldTick, CurrTick: DWord;
  //

  ActiveTabXFSheetInfo: TTabXFSheetInfo;
  ActiveSheetComponPropsInfo: TSheetComponPropsInfo;
begin
  ClearNodes;
  ActiveTabXFSheetInfo := FXLSPreview.ActiveTabXFSheetInfo; //FActiveTabXFSheetInfo;
  if ActiveTabXFSheetInfo <> nil then
  begin
    ActiveSheetComponPropsInfo := TSheetComponPropsInfo(ActiveTabXFSheetInfo.RelatedObject);

    Screen.Cursor := crHourGlass;
    try
      tvComponents.OnStateChanging := nil;
      BeginProgress;
      try
        lvExistsObjects.Items.Clear;

        //*** Скрипт проверки существования ресурса по шифру
        QSelect := TF_Main(GForm).DM.Query_Select;
        SetSQLToFIBQuery(QSelect, GetSQLByParams(qtSelect, tnNBResources,
          'UPPER('+fnCypher+') = :'+fnCypher, nil, fnID), false);

        //*** Вкидываем в дерево данные из Excel
        for i := 0 to FXLSPreview.ActiveTabXFSheetInfo.RowCount - 1 do
        begin
          CurrCypher := FXLSPreview.Xf.Workbook.Sheets[ActiveTabXFSheetInfo.SheetIndex].Cells[i, ActiveSheetComponPropsInfo.NormResCypherColumIndex].ValueAsString;
          CurrPriceStr := FXLSPreview.Xf.Workbook.Sheets[ActiveTabXFSheetInfo.SheetIndex].Cells[i, ActiveSheetComponPropsInfo.ResPriceColumIndex].ValueAsString;
          CurrName := FXLSPreview.Xf.Workbook.Sheets[ActiveTabXFSheetInfo.SheetIndex].Cells[i, ActiveSheetComponPropsInfo.NormResNameColumIndex].ValueAsString;
          CurrIzm := FXLSPreview.Xf.Workbook.Sheets[ActiveTabXFSheetInfo.SheetIndex].Cells[i, ActiveSheetComponPropsInfo.NormResIzmColumIndex].ValueAsString;
          CurrResTypeStr := FXLSPreview.Xf.Workbook.Sheets[ActiveTabXFSheetInfo.SheetIndex].Cells[i, ActiveSheetComponPropsInfo.ResTypeColumIndex].ValueAsString;

          CurrResType := GetResourceTypeByName(CurrResTypeStr);
          CurrResType := GetResourceTypeCorrectByCypher(CurrCypher, CurrResType);

          CurrPrice := 0;
          CurrPriceStr := CorrectStrToFloat(CurrPriceStr);

          CanUsePosition := true;
          try
            CurrPrice := StrToFloatU(CurrPriceStr);
          except
          end;
          if CurrCypher <> '' then
          begin
            QSelect.Close;
            QSelect.Params[0].AsString := AnsiUpperCase(CurrCypher);
            QSelect.ExecQuery;
            if QSelect.Eof then
            begin
              NewNode := tvComponents.Items.Add(nil, '');
              NewNode.StateIndex := STATE_CHECKED;

              NewNodeResourceInfo := TNodeObjectInfo.Create(NewNode);

              NewNodeResourceInfo.ID := 0;
              NewNodeResourceInfo.Cypher := CurrCypher;
              NewNodeResourceInfo.Name := CurrName;
              NewNodeResourceInfo.Izm := CurrIzm;
              NewNodeResourceInfo.CurrPrice := 0;
              NewNodeResourceInfo.NewPriceInXFCurrency := CurrPrice;
              NewNodeResourceInfo.ResType := CurrResType;

              NewNode.Text := NewNodeResourceInfo.Cypher;
              NewNode.Data := NewNodeResourceInfo;

              NewNode.Cells[ciCypher] := NewNodeResourceInfo.Cypher;
              NewNode.Cells[ciName] := NewNodeResourceInfo.Name;
              NewNode.Cells[ciIzm] := NewNodeResourceInfo.Izm;

              //CurrencyValue := GetPriceInXLSUOM(NewNodeComponInfo.CurrPrice, NewNodeComponInfo);
              //NewNode.Cells[ciCurrPrice] := FloatToStr(RoundCP(NewNodeComponInfo.CurrPrice)) +' '+ NewNodeComponInfo.CurrencyM.NameBrief;

              //*** Определить валюту ресурса
              NewNodeResourceInfo.CurrencyM := TF_Main(GForm).GCurrencyM;

              // Тип ресурса
              NewNode.Cells[ciResType] := GetResourceTypeName(NewNodeResourceInfo.ResType);
              if NewNode.Cells[ciResType] = '' then
              begin
                NewNode.Cells[ciResType] := cNoDefined;
                NewNode.StateIndex := STATE_UNCHECKED;
              end;
            end
            else
              AddNormResInfoToListView(CurrCypher, CurrName, CurrIzm, QSelect.Fields[0].AsInteger, lvExistsObjects);
          end;
          StepProgress;
        end;
      finally
        EndProgress;
      end;
      tvComponents.OnStateChanging := tvComponentsStateChanging;
    finally
      Screen.Cursor := crDefault;
    end;
    FISLoadedResources := true;
  end;
end;

procedure TF_MasterUpdatePrice.LoadResourcePricesFromXF;
var
  Node: TFlyNode;
  NodeResourceInfo: TNodeObjectInfo;
  i: Integer;
begin
  for i := 0 to tvComponents.Items.Count - 1 do
  begin
    Node := tvComponents.Items[i];
    NodeResourceInfo := TNodeObjectInfo(Node.Data);
    if NodeResourceInfo <> nil then
    begin
      // Новая цена из Excel
      Node.Cells[ciNewPriceInXFCurrency] := FloatToStr(RoundCP(NodeResourceInfo.NewPriceInXFCurrency)) + ' '+
        FActiveCurrency.NameBrief;
      NodeResourceInfo.NewPriceInComponCurrency := 0;
      
      if NodeResourceInfo.CurrencyM.ID = FActiveCurrency.ID then
      begin
        NodeResourceInfo.CurrencyXF := NodeResourceInfo.CurrencyM;
        NodeResourceInfo.NewPriceInComponCurrency := NodeResourceInfo.NewPriceInXFCurrency;
      end
      else
      begin
        NodeResourceInfo.CurrencyXF := FActiveCurrency;
        NodeResourceInfo.NewPriceInComponCurrency := GetPriceAfterChangeCurrency(NodeResourceInfo.NewPriceInXFCurrency,
              NodeResourceInfo.CurrencyXF, NodeResourceInfo.CurrencyM);
      end;

      Node.Cells[ciNewPriceInComponCurrency] := FloatToStr(RoundCP(NodeResourceInfo.NewPriceInComponCurrency))+ ' '+
          NodeResourceInfo.CurrencyM.NameBrief;
    end;
  end;
  FISLoadedResourcePrices := true;
end;

procedure TF_MasterUpdatePrice.LoadSelectedColumnFromSheetInfo(ADestCombo: TRzComboBox;
  ASelColumnIndex: Integer; ASrcTabXFSheetInfo: TTabXFSheetInfo);
var
  i: integer;
  SavedOnChange: TNotifyEvent;
begin
  SavedOnChange := ADestCombo.OnChange;
  ADestCombo.OnChange := nil;
  try
    ADestCombo.Clear;
    //ADestCombo.Items.Add(cNoDefined);
    //if ASrcTabXFSheetInfo.ColumnCount > 0 then
    //  for i := 0 to ASrcTabXFSheetInfo.ColumnCount - 1 do
    //    ADestCombo.Items.Add(DecToABC(i+1)); //ADestCombo.Items.Add(IntToStr(i+1));
    LoadColumnsToStrings(ADestCombo.Items, ASrcTabXFSheetInfo.ColumnCount);

    if (ASelColumnIndex <> -1) and (ASelColumnIndex <= (ASrcTabXFSheetInfo.ColumnCount - 1)) then
      ADestCombo.ItemIndex := ASelColumnIndex + 1
    else
      ADestCombo.ItemIndex := 0;
  finally
    ADestCombo.OnChange := SavedOnChange;
  end;
end;

procedure TF_MasterUpdatePrice.LoadXlsFileToForm;
var
  NewTabSheet: TRzTabSheet;
  NewTabXFSheetInfo: TTabXFSheetInfo;
  i: Integer;
begin
  {ClearXlsDataFromForm;
                                                  //Fxf.Workbook.Sheets[i].Columns[0].
  for i := 0 to Fxf.Workbook.Sheets.Count - 1 do
  begin
    NewTabSheet := TRzTabSheet.Create(nil);
    NewTabSheet.PageControl := pcXFSheets;
    NewTabSheet.Caption := Fxf.Workbook.Sheets[i].Name;

    NewTabXFSheetInfo := TTabXFSheetInfo.Create(NewTabSheet);
    NewTabXFSheetInfo.SheetIndex := i;
    NewTabXFSheetInfo.FGrid.PopupMenu := pmnuXFList;
    NewTabXFSheetInfo.FGrid.OnContextPopup := XFSheetContextPopup;
    NewTabSheet.Tag := Integer(NewTabXFSheetInfo);
  end;
  if pcXFSheets.PageCount > 0 then
    pcXFSheets.ActivePage := pcXFSheets.Pages[0];

  FIsLoadedXlsFile := true;}

  FXLSPreview.ShowXLS;
  FIsLoadedXlsFile := true;
end;

procedure TF_MasterUpdatePrice.SelectCurrComponentInNB;
var
  NodeComponInfo: TNodeObjectInfo;
  Node: TFlyNode;
begin
  if cbSelectCurrComponInNB.Checked then
  begin
    Node := tvComponents.Selected;
    if Node <> nil then
      if Node.Data <> nil then
        if TObject(Node.Data) is TNodeObjectInfo then
        begin
          if TNodeObjectInfo(Node.Data).ID <> 0 then
            TF_Main(GForm).SelectComponByIDInTree(TNodeObjectInfo(Node.Data).ID);
        end;
  end;
end;

procedure TF_MasterUpdatePrice.SetActiveCurrencyByGUID(AGUID: string);
var
  SprCurrency: TNBCurrency;
begin
  if AGUID <> '' then
  begin
    SprCurrency := TF_Main(GForm).GSCSBase.NBSpravochnik.GetCurrencyByGUID(AGUID);
    if SprCurrency <> nil then
      FActiveCurrency := SprCurrency.Data;
  end;
end;

procedure TF_MasterUpdatePrice.SetCaptionToStepPages;
var
  i: Integer;
  StepPageInfo: TStepSheetInfo;
begin
  for i := 0 to FStepSheets.Count - 1 do
  begin
    StepPageInfo := TStepSheetInfo(TRzTabSheet(FStepSheets[i]).Tag);

    if StepPageInfo <> nil then
    begin
      StepPageInfo.FPanelCaption.Alignment := taLeftJustify;
      StepPageInfo.FPanelCaption.Caption := '  '+IntToStr(i+1) +'.'+ StepPageInfo.FCaptionValue;
      //StepPageInfo.FPanelCaption.Color := clBlue;
      //StepPageInfo.FPanelCaption.Font.Color := clWhite;
      //StepPageInfo.FPanelCaption.Font.Size := 10;
      StepPageInfo.FPanelCaption.Font.Style := StepPageInfo.FPanelCaption.Font.Style + [fsBold];
      StepPageInfo.FPanelCaption.Height := 29;
    end;
  end;
end;

procedure TF_MasterUpdatePrice.SetControls;
var
  CurrStepIndex: Integer;
begin
  CurrStepIndex := GetCurrStepIndex;

  btBack.Enabled := CurrStepIndex > 0;

  if CurrStepIndex = (FStepSheets.Count - 1) then
    btNext.Caption := cMasterCableCanalTracing_Msg15
  else
    btNext.Caption := cMasterCableCanalTracing_Msg14;

  if pcUpdatePrice.ActivePage = tsSelectColums then
    if FPanelWithSheetParams <> nil then
      gbSheetProps.Height := FPanelWithSheetParams.Height + 15;
end;

procedure TF_MasterUpdatePrice.SetSateToAllComponNodes(AState: Integer);
var
  i: integer;
  CanSetState: Boolean;
  Node: TFlyNode;
begin
  tvComponents.OnStateChanging := nil;
  try
    for i := 0 to tvComponents.Items.Count - 1 do
    begin
      Node := tvComponents.Items[i];

      CanSetState := true;
      if FFormMode = fmImportResources then
        if GetResourceTypeByName(Node.Cells[ciResType]) = -1 then
          CanSetState := false;

      if CanSetState then
        Node.StateIndex := AState;
    end;
  finally
    tvComponents.OnStateChanging := tvComponentsStateChanging;
  end;
end;


procedure TF_MasterUpdatePrice.UpdatePrices;
var
  Node: TFlyNode;
  NodeComponInfo: TNodeObjectInfo;
  SrcComponInfo: TObjectList;
  i, j: Integer;
  QOperat: TpFIBQuery;
  LookedComponsID: TIntList;
  ExistComponCount: Integer;
  LackComponCount: Integer;
  NBRootCatalog: TSCSCatalog;
  NBCatalog: TSCSCatalog;
  ProgressStepCount: Integer;
  UpdateFields: TStringList;
  UpdValue: String;

  ActiveSheetComponPropsInfo: TSheetComponPropsInfo;
  //PropColumnsMTBoolmark: String;
  PropColumnsMTBoolmark: TBookMark;
begin
  FReloadNBTree := false;
  FAllSuppliesKinds := nil;

  SrcComponInfo := TObjectList.Create(false);
  ActiveSheetComponPropsInfo := TSheetComponPropsInfo(FXLSPreview.ActiveTabXFSheetInfo.RelatedObject);

  LackComponCount := 0;
  ExistComponCount := 0;

  //*** Определить исходные ветви обновляемых компонент
  for i := 0 to tvComponents.Items.Count - 1 do
  begin
    Node := tvComponents.Items[i];
    if Node.StateIndex = STATE_CHECKED then
      if Node.Data <> nil then
        if TObject(Node.Data) is TNodeObjectInfo then
        begin
          NodeComponInfo := TNodeObjectInfo(Node.Data);
          if ((NodeComponInfo.NewPriceInComponCurrency <> 0) and (cbColumnPrice.ItemIndex <> 0)) or (cbColumnPrice.ItemIndex = 0) then
          begin
            SrcComponInfo.Add(NodeComponInfo);
            if NodeComponInfo.ID = 0 then
              Inc(LackComponCount)
            else
              Inc(ExistComponCount);
          end;
        end;
  end;

  ProgressStepCount := 0;
  if (cbColumnPrice.ItemIndex > 0) and cbApplyParamsFroExist.Checked then
    ProgressStepCount := SrcComponInfo.Count * 2;
  // наименования и ед. изм
  //if (cbColumnName.ItemIndex > 0) {cbUpdateNames.Checked} or (cbColumnIzm.ItemIndex > 0) then
  //  ProgressStepCount := ProgressStepCount + SrcComponInfo.Count;
  
  //if cbAddLackCompons.Checked then
    ProgressStepCount := ProgressStepCount + SrcComponInfo.Count; // без if cbAddLackCompons.Checked then
  BeginProgress('', ProgressStepCount);

  ActiveSheetComponPropsInfo.DefineColumnsNums;
  //PropColumnsMTBoolmark := ActiveSheetComponPropsInfo.FMT.Bookmark;
  PropColumnsMTBoolmark := ActiveSheetComponPropsInfo.FMT.GetBookmark;
  ActiveSheetComponPropsInfo.FMT.DisableControls;
  try
    QOperat := TF_Main(GForm).DM.Query_Operat;

    //*** Внести новые цены
    if (cbColumnPrice.ItemIndex > 0) and cbApplyParamsFroExist.Checked then
    begin
      SetSQLToFIBQuery(QOperat, GetSQLByParams(qtUpdate, tnComponent, fnID+' = :'+fnID, nil, fnPrice), false);
      for i := 0 to SrcComponInfo.Count - 1 do
      begin
        NodeComponInfo := TNodeObjectInfo(SrcComponInfo[i]);
        if NodeComponInfo.ID <> 0 then
        begin
          QOperat.Close;
          QOperat.ParamByName(fnID).AsInteger := NodeComponInfo.ID;
          QOperat.ParamByName(fnPrice).AsFloat := GetPriceInNBUOM(NodeComponInfo.NewPriceInComponCurrency, NodeComponInfo);
          QOperat.ExecQuery;
          Inc(ExistComponCount);
        end
        else
          Inc(LackComponCount);
        StepProgress;
      end;
      QOperat.Close;

      //*** Обновить цены компонент парентов
      LookedComponsID := TIntList.Create;
      for i := 0 to SrcComponInfo.Count - 1 do
      begin
        NodeComponInfo := TNodeObjectInfo(SrcComponInfo[i]);
        if NodeComponInfo.ID <> 0 then
        begin
          TF_Main(GForm).CalcPriceForParents(NodeComponInfo.ID, LookedComponsID);
        end;
        StepProgress;
      end;
      FreeAndNil(LookedComponsID);
    end;

    //*** Обновить наименования компонент и Ед. изм
    //if (cbColumnName.ItemIndex > 0){cbUpdateNames.Checked} or (cbColumnIzm.ItemIndex > 0) then
    //begin
    //  UpdateFields := TStringList.Create;
    //  if cbColumnName.ItemIndex > 0 then //if cbUpdateNames.Checked then
    //    UpdateFields.Add(fnName);
    //  if cbColumnIzm.ItemIndex > 0 then
    //    UpdateFields.Add(fnIzm);
    //
    //  SetSQLToFIBQuery(QOperat, GetSQLByParams(qtUpdate, tnComponent, fnID+' = :'+fnID, UpdateFields, ''), false);
    //  for i := 0 to SrcComponInfo.Count - 1 do
    //  begin
    //    NodeComponInfo := TNodeObjectInfo(SrcComponInfo[i]);
    //    if (NodeComponInfo.ID <> 0) and (NodeComponInfo.NewName <> '') then
    //    begin
    //      QOperat.Close;
    //      QOperat.ParamByName(fnID).AsInteger := NodeComponInfo.ID;
    //      //QOperat.ParamByName(fnName).AsString := NodeComponInfo.NewName;
    //
    //      for j := 0 to UpdateFields.Count - 1 do
    //      begin
    //        UpdValue := '';
    //        if UpdateFields[j] = fnName then
    //          UpdValue := NodeComponInfo.NewName
    //        else if UpdateFields[j] = fnIzm then
    //          UpdValue := NodeComponInfo.Izm;
    //        QOperat.ParamByName(UpdateFields[j]).AsString := UpdValue;
    //      end;
    //
    //      QOperat.ExecQuery;
    //    end;
    //    StepProgress;
    //  end;
    //  QOperat.Close;
    //
    //  UpdateFields.Free;
    //end;


    //if cbAddLackCompons.Checked then
//    begin
//      if LackComponCount > 0 then
//      begin
//        // Создаем ветку в дереве
//        NBRootCatalog := TF_Main(GForm).CreateNBCatalog(nil, cMasterUpdatePrice_Msg10+' '+DateTimeToStr(Now));
//        if NBRootCatalog <> nil then
//        begin
//          TF_Main(GForm).DM.SetObjectCurrencyAsMain(NBRootCatalog.ID, FActiveCurrency.ID);
//
//          for i := 0 to SrcComponInfo.Count - 1 do
//          begin
//            NodeComponInfo := TNodeObjectInfo(SrcComponInfo[i]);
//            if (NodeComponInfo.ID = 0) then
//            begin
//              NBCatalog := DefineChildCatalogFromPath(NBRootCatalog, NodeComponInfo.FCatalogs);
//              AddComponToNB(NBCatalog, NodeComponInfo);
//            end;
//            StepProgress;
//          end;
//          FreeandNil(NBRootCatalog);
//        end;
//      end
//      else
//      begin
//        for i := 0 to SrcComponInfo.Count - 1 do
//        begin
//          StepProgress;
//        end;
//      end;
//    end;


    // Создаем ветку в дереве, если вкидываем новые, или применяем структуру для существующих
    NBRootCatalog := nil;
    if ((LackComponCount > 0) and cbAddLackCompons.Checked) or
       ((ExistComponCount > 0) and cbApplyParamsFroExist.Checked and cbApplyStructureForExist.Checked)
     then
    begin
      NBRootCatalog := TF_Main(GForm).CreateNBCatalog(nil, cMasterUpdatePrice_Msg10+' '+DateTimeToStr(Now));
      TF_Main(GForm).DM.SetObjectCurrencyAsMain(NBRootCatalog.ID, FActiveCurrency.ID);
    end;

    for i := 0 to SrcComponInfo.Count - 1 do
    begin
      NodeComponInfo := TNodeObjectInfo(SrcComponInfo[i]);
      if ((NodeComponInfo.ID = 0) and cbAddLackCompons.Checked) or
         ((NodeComponInfo.ID <> 0) and cbApplyParamsFroExist.Checked)
        then
      begin
        NBCatalog := nil;
        if NBRootCatalog <> nil then
          // применять структуру для новых, или для существующих ели стоит опция
          if (NodeComponInfo.ID = 0) or (cbApplyStructureForExist.Checked) then
            NBCatalog := DefineChildCatalogFromPath(NBRootCatalog, NodeComponInfo.FCatalogs);
        AddUpdateComponToNB(NBCatalog, NodeComponInfo);
      end;
      StepProgress;
    end;
    if NBRootCatalog <> nil then
      FreeandNil(NBRootCatalog);
  finally
    EndProgress;
    ActiveSheetComponPropsInfo.FMT.EnableControls;
    //ActiveSheetComponPropsInfo.FMT.Bookmark := PropColumnsMTBoolmark;
    ActiveSheetComponPropsInfo.FMT.GotoBookmark(PropColumnsMTBoolmark);
    ActiveSheetComponPropsInfo.FMT.FreeBookmark(PropColumnsMTBoolmark);
  end;

  FreeAndNil(SrcComponInfo);

  if FAllSuppliesKinds <> nil then
  begin
    FreeList(FAllSuppliesKinds);
    FAllSuppliesKinds := nil;
  end;

  if FReloadNBTree then
    F_NormBase.ReloadNodes(nil);
end;

procedure TF_MasterUpdatePrice.XFSheetContextPopup(Sender: TObject; MousePos: TPoint;
  var Handled: Boolean);
begin
  FXFSheetPopupPoint := MousePos;
end;

procedure TF_MasterUpdatePrice.FXLSPreviewChangeSheet(Sender: TObject);
var
  SheetComponPropsInfo: TSheetComponPropsInfo;
  TabXFSheetInfo: TTabXFSheetInfo;
  i: Integer;
  Combo: TRzComboBox;
begin
  if Sender is TTabXFSheetInfo then
  begin
    TabXFSheetInfo := TTabXFSheetInfo(Sender);
    SheetComponPropsInfo := TSheetComponPropsInfo(TTabXFSheetInfo(Sender).RelatedObject);
    FActiveSheetComponPropsInfo := SheetComponPropsInfo;

    TcxComboBoxProperties(GT_PropColumnsColumn.Properties).Items.Clear;
    LoadColumnsToStrings(TcxComboBoxProperties(GT_PropColumnsColumn.Properties).Items, TabXFSheetInfo.ColumnCount);

    case FFormMode of
      fmUpdateCompons:
        begin
          //*** Загрузить выбранные столбци и параметры для выбранного листа
          LoadSelectedColumnFromSheetInfo(cbColumnArtNo, SheetComponPropsInfo.ArtNoColumIndex, TabXFSheetInfo);
          LoadSelectedColumnFromSheetInfo(cbColumnPrice, SheetComponPropsInfo.PriceColumIndex, TabXFSheetInfo);
          LoadSelectedColumnFromSheetInfo(cbColumnName, SheetComponPropsInfo.NameColumIndex, TabXFSheetInfo);
          LoadSelectedColumnFromSheetInfo(cbColumnIzm, SheetComponPropsInfo.IzmColumIndex, TabXFSheetInfo);
          for i := 0 to cntStructLevels - 1 do
          begin
            Combo := GetStructLevelCombo(i);
            if Combo <> nil then
              LoadSelectedColumnFromSheetInfo(Combo, SheetComponPropsInfo.StructLevelsIndex[i], TabXFSheetInfo);
          end;


          if SheetComponPropsInfo.ArtNoType = antNone then
          begin
            rbArtNoProduc.Checked := false;
            rbArtNoDistrib.Checked := false;
          end
          else
          if SheetComponPropsInfo.ArtNoType = antProduc then
            rbArtNoProduc.Checked := true
          else
          if SheetComponPropsInfo.ArtNoType = antDistrib then
            rbArtNoDistrib.Checked := true;
        end;
      fmImportNorms, fmImportResources:
        begin
          LoadSelectedColumnFromSheetInfo(cbNormResCypher, SheetComponPropsInfo.NormResCypherColumIndex, TabXFSheetInfo);
          LoadSelectedColumnFromSheetInfo(cbNormResName, SheetComponPropsInfo.NormResNameColumIndex, TabXFSheetInfo);
          LoadSelectedColumnFromSheetInfo(cbNormResIzm, SheetComponPropsInfo.NormResIzmColumIndex, TabXFSheetInfo);
          LoadSelectedColumnFromSheetInfo(cbResPrice, SheetComponPropsInfo.ResPriceColumIndex, TabXFSheetInfo);
          LoadSelectedColumnFromSheetInfo(cbResType, SheetComponPropsInfo.ResTypeColumIndex, TabXFSheetInfo);
        end;
    end;
    GT_PropColumns.DataController.DataSource := SheetComponPropsInfo.FDataSource;

    DropSelectionForSheet;
  end;
end;

procedure TF_MasterUpdatePrice.FXLSPreviewCreateSheetInfo(Sender: TObject);
var
  SheetComponPropsInfo: TSheetComponPropsInfo;
begin
  if Sender is TTabXFSheetInfo then
  begin
    SheetComponPropsInfo := TSheetComponPropsInfo.Create;
    TTabXFSheetInfo(Sender).RelatedObject := SheetComponPropsInfo;
  end;
end;

procedure TF_MasterUpdatePrice.FXLSPreviewMenuItemClick(Sender: TObject);
var
  RelatedControl: TWinControl;
  RelatedCombo: TRzComboBox;
begin
  if Sender is TMenuItem then
    if FXLSPreview.ActiveTabXFSheetInfo <> nil then
      if FXLSPreview.ActiveTabXFSheetInfo.ColumnContextPopup > 0 then
      begin
        RelatedCombo := nil;
        RelatedControl := nil;

        case TMenuItem(Sender).Tag of
          miComponArtNo:
            begin
              cbColumnArtNo.ItemIndex := FXLSPreview.ActiveTabXFSheetInfo.ColumnContextPopup;
              cbColumnArtNoChange(cbColumnArtNo);
            end;
          miComponPrice:
            begin
              cbColumnPrice.ItemIndex := FXLSPreview.ActiveTabXFSheetInfo.ColumnContextPopup;
              cbColumnPriceChange(cbColumnPrice);
            end;
          miStructLevel:
            begin
              RelatedControl := GetStructLevelCombo(GetStructLevelFromName(TMenuItem(Sender).Name, 'pmiColumnStructLevel'));
            end;
          else
          begin
            //RelatedControl := GetRelatedControlWithMenuItemByTag(TMenuItem(Sender).Tag);
            RelatedControl := FXLSPreview.GetRelatedControlWithMenuItemByTag(TMenuItem(Sender).Tag);
          end;
        end;

        if RelatedControl <> nil then
          if RelatedControl is TRzComboBox then
            RelatedCombo := TRzComboBox(RelatedControl);

        if RelatedCombo <> nil then
        begin
          RelatedCombo.ItemIndex := FXLSPreview.ActiveTabXFSheetInfo.ColumnContextPopup;
          if Assigned(RelatedCombo.OnChange) then
            RelatedCombo.OnChange(RelatedCombo);
        end;
      end;
end;


procedure TF_MasterUpdatePrice.pcUpdatePriceChange(Sender: TObject);
begin
  SetControls;
end;

procedure TF_MasterUpdatePrice.btBackClick(Sender: TObject);
var
  CurrStepIndex: Integer;
begin
  CurrStepIndex := GetCurrStepIndex;
  if CurrStepIndex > 0 then
  begin
    //pcUpdatePrice.ActivePage := pcUpdatePrice.Pages[pcUpdatePrice.ActivePageIndex - 1];
    pcUpdatePrice.ActivePage := TRzTabSheet(FStepSheets[CurrStepIndex - 1]);
    SetControls;
  end;
end;

procedure TF_MasterUpdatePrice.btNextClick(Sender: TObject);
var
  CanNext: Boolean;
  CurrStepIndex: Integer;

  procedure ShowNoDefinedValue(ACaption: String; AControl: TWinControl);
  begin
    MessageModal(ACaption, ApplicationName, MB_OK or MB_ICONINFORMATION);
    CanNext := false;
    if AControl <> nil then
      AControl.SetFocus;
  end;

begin
  try
    CurrStepIndex := GetCurrStepIndex;

    if CurrStepIndex < (FStepSheets.Count - 1) then
    begin
      CanNext := true;

      if pcUpdatePrice.ActivePage = tsSelectFileName then
      begin
        if Not FIsOpenedXlsFile then
          ShowNoDefinedValue(cMasterUpdatePrice_Msg2_1, nil)
        else
        if Not FIsLoadedXlsFile then
          LoadXlsFileToForm;
      end
      else
      if pcUpdatePrice.ActivePage = tsSelectColums then
      begin
        if FActiveSheetComponPropsInfo = nil then //if FActiveTabXFSheetInfo = nil then
          ShowNoDefinedValue(cMasterUpdatePrice_Msg2_2, nil)
        else
          case FFormMode of
            fmUpdateCompons:
              begin
                if FActiveSheetComponPropsInfo.ArtNoColumIndex = -1 then //if FActiveTabXFSheetInfo.ArtNoColumIndex = -1 then
                  ShowNoDefinedValue(cMasterUpdatePrice_Msg2_3, cbColumnArtNo)
                //else
                //if FActiveSheetComponPropsInfo.PriceColumIndex = -1 then //if FActiveTabXFSheetInfo.PriceColumIndex = -1 then
                //  ShowNoDefinedValue(cMasterUpdatePrice_Msg2_4, cbColumnPrice)
                else
                if Not FIsLoadedCurrency then
                  LoadCurrencies('');
              end;
            fmImportResources, fmImportNorms:
              begin
                if FActiveSheetComponPropsInfo.NormResCypherColumIndex = -1 then
                  ShowNoDefinedValue(cMasterUpdatePrice_Msg2_6, cbNormResCypher)
                else
                if FActiveSheetComponPropsInfo.NormResNameColumIndex = -1 then
                  ShowNoDefinedValue(cMasterUpdatePrice_Msg2_7, cbNormResName)
                else
                if FActiveSheetComponPropsInfo.NormResIzmColumIndex = -1 then
                  ShowNoDefinedValue(cMasterUpdatePrice_Msg2_8, cbNormResIzm)
                else
                if FFormMode = fmImportResources then
                begin
                  if FActiveSheetComponPropsInfo.ResPriceColumIndex = -1 then
                    ShowNoDefinedValue(cMasterUpdatePrice_Msg2_9, cbResPrice)
                  else
                  if FActiveSheetComponPropsInfo.ResTypeColumIndex = -1 then
                    ShowNoDefinedValue(cMasterUpdatePrice_Msg2_10, cbResType);
                end;

                if CanNext then
                begin
                  if FFormMode = fmImportResources then
                  begin
                    if Not FIsLoadedCurrency then
                      LoadCurrencies('');
                  end
                  else
                  if FFormMode = fmImportNorms then
                    if Not FISLoadedNorms then
                      LoadNormsFromXF;
                end;
              end;
          end;
      end
      else
      if pcUpdatePrice.ActivePage = tsSelectCurrency then
      begin
        if FActiveCurrency.GUID = '' then
          ShowNoDefinedValue(cMasterUpdatePrice_Msg2_5, cbCurrency)
        else
        begin
          if FActiveSheetComponPropsInfo <> nil then//if FActiveTabXFSheetInfo <> nil then
            if FActiveSheetComponPropsInfo.ArtNoType = antProduc then //if FActiveTabXFSheetInfo.ArtNoType = antProduc then
              tvComponents.Columns[ciArtNo].Caption := cNameArtNoProduc
            else
            if FActiveSheetComponPropsInfo.ArtNoType = antDistrib then //if FActiveTabXFSheetInfo.ArtNoType = antDistrib then
              tvComponents.Columns[ciArtNo].Caption := cNameArtNoDistrib;
          //tvComponents.Columns[ciNewPriceInXFCurrency].Caption := cMasterUpdatePrice_Msg3_4 +' '+ FActiveCurrency.NameBrief;

          case FFormMode of
            fmUpdateCompons:
              begin
                if Not FISLoadedComponents then
                  LoadComponentsFromXF;
                if Not FISLoadedComponentPrices then
                  LoadComponPricesFromXF;
                lbNoticeCurrUOM.Caption := ' '+cMasterUpdatePrice_Msg4 + ' '+GetNameUOM(GetIDFromComboBoxRz(cbUOM), true);
              end;
            fmImportResources:
              begin
                if Not FISLoadedResources then
                  LoadResourcesFromXF;
                if Not FISLoadedResourcePrices then
                  LoadResourcePricesFromXF;
              end;
          end;
        end;
      end;

      if CanNext then
      begin
        //pcUpdatePrice.ActivePage := pcUpdatePrice.Pages[pcUpdatePrice.ActivePageIndex + 1];
        pcUpdatePrice.ActivePage := TRzTabSheet(FStepSheets[CurrStepIndex + 1]);
        SetControls;
      end;
    end
    else
    if CurrStepIndex = (FStepSheets.Count - 1) then
    begin
      case FFormMode of
        fmUpdateCompons:
          begin
            UpdatePrices;
            TF_Main(GForm).RefreshNode(true);
          end;
        fmImportResources, fmImportNorms:
          begin
            ImportNormResToBase;
          end;
      end;

      ModalResult := mrOk;
      // Tolik 03/07/2017 -- сброс для CashedCompon (чтобы не пришли значения с предидущего проекта)
      if Assigned(F_ProjMan) then
        if TF_Main(F_ProjMan).CashedCompon <> nil then
          TF_Main(F_ProjMan).CashedCompon.Clear;
      if Assigned(F_NormBase) then
        if TF_Main(F_NormBase).CashedCompon <> nil then
          TF_Main(F_NormBase).CashedCompon.Clear;
      //
    end;
  except
    on E: Exception do AddExceptionToLogEx('TF_MasterUpdatePrice.btNextClick', E.Message);
  end;
end;

procedure TF_MasterUpdatePrice.FormCreate(Sender: TObject);
var
  i: Integer;

  CaptionPanels: TObjectList;
  CurrPanel: TRzPanel;

  TreeCollection: TTreeCollectionClass;
  TreeCollectionClassName: String;
  Node: TFlyNode;

  procedure AddUOMToCombo(AUOM: Integer);
  begin
    AddIDGUIDToComboRz(AUOM, '', GetNameUOM(AUOM, false), cbUOM);
  end;

  procedure AddNodeToNodes(ANodeList: TFlyNodes; ACaption: String; AData: Integer);
  var
    NewNode: TFlyNode;
  begin
    NewNode := ANodeList.Add(nil, ACaption);
    NewNode.Data := Pointer(AData);
  end;

begin
  //Fxf := nil;
  {$IF Defined(OEM_NIKOMAX)}
    cbAddLackCompons.Enabled := False;
    cbApplyStructureForExist.Enabled := False;
  {$IFEND}  

  FXLSPreview := TXLSPreview.Create(gbXLSDoc, true);
  FXLSPreview.OnCreateSheetInfo := FXLSPreviewCreateSheetInfo;
  FXLSPreview.OnChangeSheet := FXLSPreviewChangeSheet;
  FXLSPreview.OnMenuItemClick := FXLSPreviewMenuItemClick;
  
  FStepSheets := TObjectList.Create(false);

  edFileNameXls.ReadOnly := true;

  for i := 0 to pcUpdatePrice.PageCount - 1 do
    pcUpdatePrice.Pages[i].TabVisible := false;

  pcXFSheets.ShowFullFrame := false;
  pcXFSheets.TabHeight := 0;
  pcXFSheets.TabOrientation := toBottom;
  pcXFSheets.TabStyle := tsRoundCorners;
  //pcXFSheets.UseColoredTabs := true;

  {CaptionPanels := TObjectList.Create(false);
  CaptionPanels.Add(pnCaption1);
  CaptionPanels.Add(pnCaption2);
  CaptionPanels.Add(pnCaption3);
  CaptionPanels.Add(pnCaption4);
  for i := 0 to CaptionPanels.Count - 1 do
  begin
    CurrPanel := TRzPanel(CaptionPanels[i]);
    CurrPanel.Alignment := taLeftJustify;
    CurrPanel.Caption := '  '+IntToStr(i+1) +'.'+ CurrPanel.Caption;
    //CurrPanel.Color := clBlue;
    //CurrPanel.Font.Color := clWhite;
    //CurrPanel.Font.Size := 10;
    CurrPanel.Font.Style := CurrPanel.Font.Style + [fsBold];
    CurrPanel.Height := 29;
  end;
  FreeAndNil(CaptionPanels);}

  CreateStepSheetInfo(tsSelectFileName, pnCaption1);
  CreateStepSheetInfo(tsSelectColums, pnCaption2);
  CreateStepSheetInfo(tsSelectCurrency, pnCaption3);
  CreateStepSheetInfo(tsSelectComponents, pnCaption4);

  //FControlsRelatedToMenuItems := TObjectList.Create(false);
  //AddRelatedControlWithMenuItem(cbNormResCypher, miNormResCypher);
//  AddRelatedControlWithMenuItem(cbNormResName, miNormResName);
//  AddRelatedControlWithMenuItem(cbNormResIzm, miNormResIzm);
//  AddRelatedControlWithMenuItem(cbResPrice, miResPrice);
//  AddRelatedControlWithMenuItem(cbResType, miResType);
//  AddRelatedControlWithMenuItem(cbColumnName, miName);
//  AddRelatedControlWithMenuItem(cbColumnIzm, miIzm);

  tvComponents.Columns.Clear;
  tvComponents.Images.Clear;
  //tvComponents.Images.AddImages(TF_Main(GForm).DM.ImageList_FlyTree);
  tvComponents.ButtonCheckedIndex := 1;
  tvComponents.ButtonGrayedIndex := 2;
  tvComponents.ButtonUnCheckedIndex := 0;

  tvComponents.ClickableColumns := false;
  tvComponents.DefaultRowHeight := 17;
  tvComponents.Indent := 17;
  tvComponents.Options := tvComponents.Options + [goColSizing, goEditing] {- [goHorzLine, goVertLine]};
  tvComponents.RightClickSelect := true;
  //tvComponents.SelectedBackgroundColor := tvclSelBackColorUnFocused;
  //tvComponents.SelectedTextColor := tvclSelTextColorUnFocused;
  tvComponents.ShowRoot := false;
  tvComponents.ShowHint := true;
  tvComponents.ShowImages := true;
  tvComponents.ShowLogic := true;
  tvComponents.ToolTips := true;

  // Артикульный номер
  TreeCollection := tvComponents.Columns.Add('', TreeCollectionClassName);
  // Шифр
  TreeCollection := tvComponents.Columns.Add(lbNormResCypher.Caption, TreeCollectionClassName);
  // Наименование компоненты
  TreeCollection := tvComponents.Columns.Add(cMasterUpdatePrice_Msg3_1, TreeCollectionClassName);
  // Ед. Изм
  TreeCollection := tvComponents.Columns.Add(lbNormResIzm.Caption, TreeCollectionClassName);
  // текущая цена компоненты
  TreeCollection := tvComponents.Columns.Add(cMasterUpdatePrice_Msg3_2, TreeCollectionClassName);
  // Новая цена в валюте Excel файла
  TreeCollection := tvComponents.Columns.Add(cMasterUpdatePrice_Msg3_4, TreeCollectionClassName);
  // Новая цена в валюте компоненты
  TreeCollection := tvComponents.Columns.Add(cMasterUpdatePrice_Msg3_3, TreeCollectionClassName);
  // Новое наименование
  TreeCollection := tvComponents.Columns.Add(cMasterUpdatePrice_Msg3_5, TreeCollectionClassName);
  // Тип ресурса
  TreeCollection := tvComponents.Columns.Add(lbResType.Caption, TreeCollectionClassName);


  tvComponents.StructureCol := ciArtNo;
  tvComponents.FixedColAsButton := false;

  {ciArtNo
  ciName
  ciCurrPrice
  ciNewPriceInComponCurrency
  ciNewPriceInXFCurrency}

  tvComponents.Columns[ciArtNo].ReadOnly := true;
  tvComponents.Columns[ciArtNo].Width := 130;

  tvComponents.Columns[ciCypher].ReadOnly := true;
  tvComponents.Columns[ciCypher].Width := 130;

  tvComponents.Columns[ciName].ReadOnly := true;
  tvComponents.Columns[ciName].Width := 220;

  tvComponents.Columns[ciIzm].ReadOnly := true;
  tvComponents.Columns[ciIzm].Width := 100;

  tvComponents.Columns[ciCurrPrice].ReadOnly := true;
  tvComponents.Columns[ciCurrPrice].Width := 100;

  tvComponents.Columns[ciNewPriceInXFCurrency].ReadOnly := true;
  //tvComponents.Columns[ciNewPriceInXFCurrency].EditorStyle.EditorType := tetCustom;
  tvComponents.Columns[ciNewPriceInXFCurrency].Width := 150;

  tvComponents.Columns[ciNewPriceInComponCurrency].ReadOnly := true;
  //tvComponents.Columns[ciNewPriceInComponCurrency].EditorStyle.EditorType := tetInteger;
  tvComponents.Columns[ciNewPriceInComponCurrency].Width := 200;

  tvComponents.Columns[ciNewName].ReadOnly := true;
  tvComponents.Columns[ciNewName].Width := tvComponents.Columns[ciName].Width;

  //tvComponents.Columns[ciResType].ReadOnly := true;
  tvComponents.Columns[ciResType].Width := 170;
  tvComponents.Columns[ciResType].EditorStyle.EditorType := tetDropDownList;
  tvComponents.Columns[ciResType].EditorStyle.ButtonType := tbtDropDown;
  tvComponents.Columns[ciResType].EditorStyle.AutoComplete := true;
  tvComponents.Columns[ciResType].EditorStyle.DropdownStyles := tvComponents.Columns[ciResType].EditorStyle.DropdownStyles + [ddsSized]; 
  AddNodeToNodes(tvComponents.Columns[ciResType].EditorStyle.Sections[0].Items, cNoDefined, -1);
  AddNodeToNodes(tvComponents.Columns[ciResType].EditorStyle.Sections[0].Items, cMakeNorm_Msg1_1, rtMat);
  AddNodeToNodes(tvComponents.Columns[ciResType].EditorStyle.Sections[0].Items, cMakeNorm_Msg1_2, rtMachMech);
  AddNodeToNodes(tvComponents.Columns[ciResType].EditorStyle.Sections[0].Items, cMakeNorm_Msg1_3, rtPrice);


  //Node := tvComponents.Items.Add(nil, 'test');
  //Node.StateIndex := STATE_CHECKED;


  {$IF NOT Defined (FINAL_SCS)}
    gbWorVerisonParams.Visible := true;
  {$ELSE IF}
    gbWorVerisonParams.Visible := false;
    //cbUpdateNames.Checked := false;
    tvComponents.Columns[ciNewName].Visible := false;
  {$IFEND}

  // Единици измерения
  AddUOMToCombo(umSantimetr);
  AddUOMToCombo(umMetr);
  AddUOMToCombo(umInch);
  AddUOMToCombo(umFoot);

  FAllSuppliesKinds := nil;
end;

procedure TF_MasterUpdatePrice.FormDestroy(Sender: TObject);
begin
  //FreeAndNil(FControlsRelatedToMenuItems);
  FreeAndNil(FStepSheets);
  FreeAndNil(FXLSPreview);

  ClearStepSheetInfo;
end;


procedure TF_MasterUpdatePrice.btSelectXlsFileClick(Sender: TObject);
var
  OpenDialog: TOpenDialog;
  
begin
  OpenDialog := TOpenDialog.Create(Self);
  OpenDialog.Title := cOpeningXlsFile;
  //OpenDialog.InitialDir := ExtractMyDocDir;
  OpenDialog.DefaultExt := '*.'+enXls;
  OpenDialog.FileName := '';
  OpenDialog.Filter := GetDialogFilter(exdXls, enXls);
  OpenDialog.Options := OpenDialog.Options - [ofNoChangeDir] + [ofFileMustExist];

  if OpenDialog.Execute then
  begin
    Application.ProcessMessages;
    //22.11.2011 if AnsiUpperCaseFileName(OpenDialog.FileName) <> AnsiUpperCaseFileName(FOpenedFileName) then
    begin
      {FIsOpenedXlsFile := true;
      try
        Fxf.OpenFile(OpenDialog.FileName);
      except
        on E: Exception do
        begin
          FIsOpenedXlsFile := false;
          MessageModal(cNoOpenFileB+' '+OpenDialog.FileName, ApplicationName, MB_OK or MB_ICONINFORMATION);
        end;
      end;}
      FIsOpenedXlsFile := false;
      if FXLSPreview.OpenFromFile(OpenDialog.FileName) then
        FIsOpenedXlsFile := true
      else
        MessageModal(cNoOpenFileB+' '+OpenDialog.FileName, ApplicationName, MB_OK or MB_ICONINFORMATION);

      if FIsOpenedXlsFile then
      begin
        DropSelectionForFile;
        FIsOpenedXlsFile := true;
        FOpenedFileName := OpenDialog.FileName;

        edFileNameXls.Text := OpenDialog.FileName; 
      end;
    end;
  end;
  FreeAndNil(OpenDialog);
end;

procedure TF_MasterUpdatePrice.pcXFSheetsChange(Sender: TObject);
var
  TabXFSheetInfo: TTabXFSheetInfo;
  TabSheet: TRzTabSheet;
  i, j: integer;
  TestStr: String;

  SheetCells: TCells;
  RangeRect: TRangeRect;
begin
  {try
    TabSheet := TRzPageControl(Sender).ActivePage;

    if TabSheet <> nil then
    begin
      //*** Загрузить лист книги
      TabXFSheetInfo := nil;
      if TabSheet.Tag <> 0 then
        TabXFSheetInfo := TTabXFSheetInfo(TabSheet.Tag);
      if TabXFSheetInfo <> nil then
      begin
        //*** Загрузить лист из Excel файла
        if TabXFSheetInfo.IsLoadedSheet = false then
        begin
          Screen.Cursor := crHourGlass;
          try
            TabXFSheetInfo.IsLoadedSheet := true;
            if Fxf.Workbook.Sheets[TabSheet.TabIndex].GetUsedRect(RangeRect) then
            begin
              TabXFSheetInfo.ColumnCount := RangeRect.ColumnTo - RangeRect.ColumnFrom + 1;
              TabXFSheetInfo.RowCount := RangeRect.RowTo - RangeRect.RowFrom + 1;
            end
            else
            begin
              //TabXFSheetInfo.ColumnCount := Fxf.Workbook.Sheets[TabSheet.TabIndex].Columns.Count;
              //TabXFSheetInfo.RowCount := Fxf.Workbook.Sheets[TabSheet.TabIndex].Rows.Count;
                                        //Fxf.Workbook.Sheets[TabSheet.TabIndex].Cells.Count
              TabXFSheetInfo.ColumnCount := Fxf.Workbook.Sheets[TabSheet.TabIndex].Cells.Count;
              TabXFSheetInfo.RowCount := TabXFSheetInfo.ColumnCount;
            end;

            if (TabXFSheetInfo.ColumnCount <= 1) or (TabXFSheetInfo.ColumnCount > 500) then
              TabXFSheetInfo.ColumnCount := 500;
            if (TabXFSheetInfo.RowCount <= 1) or (TabXFSheetInfo.RowCount > 20000) then
              TabXFSheetInfo.RowCount := 20000;

            //*** Количество столбцов и строк в гриде
            TabXFSheetInfo.FGrid.ColCount := TabXFSheetInfo.ColumnCount + 1;
            TabXFSheetInfo.FGrid.RowCount := TabXFSheetInfo.RowCount + 1;

            if TabXFSheetInfo.FGrid.ColCount > 1 then
              TabXFSheetInfo.FGrid.FixedCols := 1;
            if TabXFSheetInfo.FGrid.RowCount > 1 then
              TabXFSheetInfo.FGrid.FixedRows := 1;

            //*** Ширина колонок
            TabXFSheetInfo.FGrid.ColWidths[0] := 25;
            for i := 0 to TabXFSheetInfo.ColumnCount - 1 do
              TabXFSheetInfo.FGrid.ColWidths[i+1] := Fxf.Workbook.Sheets[TabSheet.TabIndex].Columns[i].WidthPx;
            //*** Высота строк
            TabXFSheetInfo.FGrid.DefaultRowHeight := 19;

            //*** Значения фиксированных столбцов, строк
            for i := 0 to TabXFSheetInfo.ColumnCount - 1 do
              TabXFSheetInfo.FGrid.Cells[i+1, 0] := DecToABC(i+1); //IntToStr(i+1);
            for i := 0 to TabXFSheetInfo.RowCount - 1 do
              TabXFSheetInfo.FGrid.Cells[0, i+1] := IntToStr(i+1);

            try
              //*** Значения ячеек
              SheetCells := Fxf.Workbook.Sheets[TabSheet.TabIndex].Cells;
              for i := 0 to TabXFSheetInfo.ColumnCount - 1 do
                for j := 0 to TabXFSheetInfo.RowCount - 1 do
                begin
                  //TestStr := Fxf.Workbook.Sheets[TabSheet.TabIndex].Cells.Cell[j, i].ValueAsString;
                  //Fxf.Workbook.Sheets[TabSheet.TabIndex].Cells.Cell[j, i].Value;

                  //TabXFSheetInfo.FGrid.Cells[i+1, j+1] := Fxf.Workbook.Sheets[TabSheet.TabIndex].Cells.Cell[j, i].ValueAsString;
                  TabXFSheetInfo.FGrid.Cells[i+1, j+1] := SheetCells.Cell[j, i].ValueAsString;
                end;
            except
            end;
          finally
            Screen.Cursor := crDefault;
          end;
        end;

        //*** Загрузить выбранные столбци и параметры для выбранного листа
        FActiveTabXFSheetInfo := nil;

        LoadSelectedColumnFromSheetInfo(cbColumnArtNo, TabXFSheetInfo.ArtNoColumIndex, TabXFSheetInfo);
        LoadSelectedColumnFromSheetInfo(cbColumnPrice, TabXFSheetInfo.PriceColumIndex, TabXFSheetInfo);
        LoadSelectedColumnFromSheetInfo(cbColumnName, TabXFSheetInfo.NameColumIndex, TabXFSheetInfo);
        if TabXFSheetInfo.ArtNoType = antNone then
        begin
          rbArtNoProduc.Checked := false;
          rbArtNoDistrib.Checked := false;
        end
        else
        if TabXFSheetInfo.ArtNoType = antProduc then
          rbArtNoProduc.Checked := true
        else
        if TabXFSheetInfo.ArtNoType = antDistrib then
          rbArtNoDistrib.Checked := true;

        FActiveTabXFSheetInfo := TabXFSheetInfo;
        DropSelectionForSheet;
      end;
    end;
  except
    on E: Exception do AddExceptionToLogEx('TF_MasterUpdatePrice.pcXFSheetsChange', E.Message);
  end;}
end;

procedure TF_MasterUpdatePrice.Timer_OnExecuteTimer(Sender: TObject);
begin
  TTimer(Sender).Enabled := false;
  btSelectXlsFile.Click;
end;

procedure TF_MasterUpdatePrice.cbColumnArtNoChange(Sender: TObject);
begin
  {if FActiveTabXFSheetInfo <> nil then
  begin
    if TRzComboBox(Sender).ItemIndex > 0 then
      FActiveTabXFSheetInfo.ArtNoColumIndex := TRzComboBox(Sender).ItemIndex - 1
    else
      FActiveTabXFSheetInfo.ArtNoColumIndex := 0;

    //FISLoadedComponents := false;
    DropSelectionForSheet;
  end; }

  if FActiveSheetComponPropsInfo <> nil then
  begin
    if TRzComboBox(Sender).ItemIndex > 0 then
      FActiveSheetComponPropsInfo.ArtNoColumIndex := TRzComboBox(Sender).ItemIndex - 1
    else
      FActiveSheetComponPropsInfo.ArtNoColumIndex := 0;

    //FISLoadedComponents := false;
    DropSelectionForSheet;
  end;
end;

procedure TF_MasterUpdatePrice.cbColumnPriceChange(Sender: TObject);
begin
  {if FActiveTabXFSheetInfo <> nil then
  begin
    if TRzComboBox(Sender).ItemIndex > 0 then
      FActiveTabXFSheetInfo.PriceColumIndex := TRzComboBox(Sender).ItemIndex - 1
    else
      FActiveTabXFSheetInfo.PriceColumIndex := 0;

    FIsLoadedCurrency := false;
    DropSelectionForPrices;
  end;}
  if FActiveSheetComponPropsInfo <> nil then
  begin
    if TRzComboBox(Sender).ItemIndex > 0 then
      FActiveSheetComponPropsInfo.PriceColumIndex := TRzComboBox(Sender).ItemIndex - 1
    else
      FActiveSheetComponPropsInfo.PriceColumIndex := 0;

    FIsLoadedCurrency := false;
    DropSelectionForSheet; //DropSelectionForPrices;
  end;
end;

procedure TF_MasterUpdatePrice.cbColumnNameChange(Sender: TObject);
begin
  {if FActiveTabXFSheetInfo <> nil then
  begin
    if TRzComboBox(Sender).ItemIndex > 0 then
      FActiveTabXFSheetInfo.NameColumIndex := TRzComboBox(Sender).ItemIndex - 1
    else
      FActiveTabXFSheetInfo.NameColumIndex := 0;

    //FIsLoadedCurrency := false;
    DropSelectionForSheet;
  end;}

  if FActiveSheetComponPropsInfo <> nil then
  begin
    if TRzComboBox(Sender).ItemIndex > 0 then
      FActiveSheetComponPropsInfo.NameColumIndex := TRzComboBox(Sender).ItemIndex - 1
    else
      FActiveSheetComponPropsInfo.NameColumIndex := 0;

    //FIsLoadedCurrency := false;
    DropSelectionForSheet;
  end;
end;


procedure TF_MasterUpdatePrice.rbArtNoProducClick(Sender: TObject);
begin
  {if FActiveTabXFSheetInfo <> nil then
  begin
    FActiveTabXFSheetInfo.ArtNoType := antProduc;
    //FISLoadedComponents := false;
    DropSelectionForSheet;
  end;}

  if FActiveSheetComponPropsInfo <> nil then
  begin
    FActiveSheetComponPropsInfo.ArtNoType := antProduc;
    //FISLoadedComponents := false;
    DropSelectionForSheet;
  end;
end;

procedure TF_MasterUpdatePrice.rbArtNoDistribClick(Sender: TObject);
begin
  {if FActiveTabXFSheetInfo <> nil then
  begin
    FActiveTabXFSheetInfo.ArtNoType := antDistrib;
    FISLoadedComponents := false;
  end;}

  if FActiveSheetComponPropsInfo <> nil then
  begin
    FActiveSheetComponPropsInfo.ArtNoType := antDistrib;
    FISLoadedComponents := false;
  end;
end;

procedure TF_MasterUpdatePrice.cbColumnSheetParamChange(Sender: TObject);
var
  ptrColumnIndex: ^Integer;
  ColumnIndex: Integer;
  StructLevelNum: Integer;
begin
  if FActiveSheetComponPropsInfo <> nil then
  begin
    ptrColumnIndex := nil;
    //ptrColumnIndex := @FActiveSheetComponPropsInfo.ArtNoColumIndex;
    StructLevelNum := -1;

    case TRzComboBox(Sender).Tag of
      miNormResCypher:
        ptrColumnIndex := @FActiveSheetComponPropsInfo.NormResCypherColumIndex;
      miNormResName:
        ptrColumnIndex := @FActiveSheetComponPropsInfo.NormResNameColumIndex;
      miNormResIzm:
        ptrColumnIndex := @FActiveSheetComponPropsInfo.NormResIzmColumIndex;
      miResPrice:
        ptrColumnIndex := @FActiveSheetComponPropsInfo.ResPriceColumIndex;
      miResType:
        ptrColumnIndex := @FActiveSheetComponPropsInfo.ResTypeColumIndex;
      miName:
        ptrColumnIndex := @FActiveSheetComponPropsInfo.NameColumIndex;
      miIzm:
        ptrColumnIndex := @FActiveSheetComponPropsInfo.IzmColumIndex;
      miStructLevel:
        StructLevelNum := GetStructLevelFromName(TRzComboBox(Sender).Name, 'cbStructLevel');
    end;

    if (ptrColumnIndex <> nil) or (StructLevelNum <> -1) then
    begin
      ColumnIndex := 0;
      if TRzComboBox(Sender).ItemIndex > 0 then
        ColumnIndex := TRzComboBox(Sender).ItemIndex - 1;

      if ptrColumnIndex <> nil then
      begin
        //if TRzComboBox(Sender).ItemIndex > 0 then
        //  ptrColumnIndex^ := TRzComboBox(Sender).ItemIndex - 1
        //else
        //  ptrColumnIndex^ := 0;
        ptrColumnIndex^ := ColumnIndex;
      end
      else if StructLevelNum <> -1 then
        FActiveSheetComponPropsInfo.StructLevelsIndex[StructLevelNum] := ColumnIndex;

      //FISLoadedComponents := false;
      DropSelectionForSheet;
    end;
  end;
end;


procedure TF_MasterUpdatePrice.btSelectCurrencyClick(Sender: TObject);
var
  CurrencyID: Integer;
  SprCurrency: TNBCurrency;
begin
  CurrencyID := 0;
  if FActiveCurrency.ID <> 0 then
    CurrencyID := FActiveCurrency.ID;

  CurrencyID := TF_Main(GForm).DM.GetCurrencyIDFromGuide(CurrencyID, fmEdit);
  if CurrencyID <> 0 then
    if CurrencyID <> FActiveCurrency.ID then
    begin
      SprCurrency := TF_Main(GForm).GSCSBase.NBSpravochnik.GetCurrencyByID(CurrencyID);
      if SprCurrency <> nil then
      begin
        LoadCurrencies(SprCurrency.Data.GUID);
        SetActiveCurrencyByGUID(SprCurrency.Data.GUID);
        //FISLoadedComponentPrices := false;
        DropSelectionForPrices;
      end;
    end;
end;

procedure TF_MasterUpdatePrice.cbCurrencyChange(Sender: TObject);
var
  GUIDCurrency: String;
begin
  GUIDCurrency := GetGUIDFromComboBoxRz(TRzComboBox(Sender));
  if GUIDCurrency = '' then
    ZeroMemory(@FActiveCurrency, SizeOf(TCurrency))
  else
    SetActiveCurrencyByGUID(GUIDCurrency);
  //FISLoadedComponentPrices := false;
  DropSelectionForPrices;
end;

procedure TF_MasterUpdatePrice.btUpdatePricesClick(Sender: TObject);
begin
  LoadComponPricesFromXF;
end;

procedure TF_MasterUpdatePrice.cbSelectCurrComponInNBClick(
  Sender: TObject);
begin
  SelectCurrComponentInNB;
end;

procedure TF_MasterUpdatePrice.tvComponentsSelectedChanged(OldNode,
  NewNode: TFlyNode);
begin
  SelectCurrComponentInNB;
end;

procedure TF_MasterUpdatePrice.btCheckAllComponsClick(Sender: TObject);
begin
  SetSateToAllComponNodes(STATE_CHECKED);
end;

procedure TF_MasterUpdatePrice.btUnCheckAllComponsClick(Sender: TObject);
begin
  SetSateToAllComponNodes(STATE_UNCHECKED);
end;

procedure TF_MasterUpdatePrice.tvComponentsStateChanging(Node: TFlyNode;
  var AllowChange: Boolean);
var
  ResType: Integer;  
begin
  if FFormMode = fmImportResources then
    if GetResourceTypeByName(Node.Cells[ciResType]) = -1 then
    begin
      AllowChange := false;
      MessageModal(cMasterUpdatePrice_Msg8, ApplicationName, MB_OK or MB_ICONINFORMATION);
    end;
end;

procedure TF_MasterUpdatePrice.pmiSetColAsArticulClick(Sender: TObject);
var
  CursorCol: Integer;
  CursorRow: Integer;
  ScrPos: TPoint;
  ClientPos: TPoint;
begin
  {if FActiveTabXFSheetInfo <> nil then
  begin
    //GetCursorPos(ScrPos);
    //ClientPos := FActiveTabXFSheetInfo.FGrid.ScreenToClient(ScrPos);
    FActiveTabXFSheetInfo.FGrid.MouseToCell(FXFSheetPopupPoint.X, FXFSheetPopupPoint.Y, CursorCol, CursorRow);

    if CursorCol > 0 then
    begin
      cbColumnArtNo.ItemIndex := CursorCol;
      cbColumnArtNoChange(cbColumnArtNo);
    end;
  end;}
end;

procedure TF_MasterUpdatePrice.pmiSetColAsPriceClick(Sender: TObject);
var
  CursorCol: Integer;
  CursorRow: Integer;
begin
  {if FActiveTabXFSheetInfo <> nil then
  begin
    FActiveTabXFSheetInfo.FGrid.MouseToCell(FXFSheetPopupPoint.X, FXFSheetPopupPoint.Y, CursorCol, CursorRow);

    if CursorCol > 0 then
    begin
      cbColumnPrice.ItemIndex := CursorCol;
      cbColumnPriceChange(cbColumnPrice);
    end;
  end;}
end;


procedure TF_MasterUpdatePrice.cbUOMChange(Sender: TObject);
begin
  FXLSUOM := GetIDFromComboBoxRz(cbUOM);
  DropSelectionForPrices;
end;

{ TXLSPreview }

function TXLSPreview.AddMenuItem(ACaption: String; ATag: Integer; ARelatedControl: TWinControl=nil): TMenuItem;
begin
  Result := TMenuItem.Create(FPopupMenu);
  Result.Caption := ACaption;
  if ACaption <> '-' then
    Result.OnClick := FPopupMenuItemClick;
  Result.Tag := ATag;

  FPopupMenu.Items.Add(Result);

  if ARelatedControl <> nil then
    AddRelatedControlWithMenuItem(ARelatedControl, ATag);
end;

procedure TXLSPreview.AddRelatedControlWithMenuItem(AControl: TWinControl; ATag: Integer);
begin
  AControl.Tag := ATag;
  FControlsRelatedToMenuItems.Add(AControl);
end;


function TXLSPreview.GetRelatedControlWithMenuItemByTag(ATag: Integer): TWinControl;
var
  RelatedControl: TWinControl;
  i: integer;
begin
  Result := nil;
  for i := 0 to FControlsRelatedToMenuItems.Count - 1 do
  begin
    RelatedControl := TWinControl(FControlsRelatedToMenuItems[i]);
    if RelatedControl.Tag = ATag then
    begin
      Result := RelatedControl;
      Break; //// BREAK ////
    end;
  end;
end;

procedure TXLSPreview.ClearMenuItems;
begin
  FPopupMenu.Items.Clear;
  FControlsRelatedToMenuItems.Clear;
end;

procedure TXLSPreview.ClearPages;
var
  CurrPage: TRzTabSheet;
  TabXFSheetInfo: TTabXFSheetInfo;
begin
  while FpcXFSheets.PageCount > 0 do
  begin
    CurrPage := FpcXFSheets.Pages[0];
    TabXFSheetInfo := TTabXFSheetInfo(CurrPage.Tag);
    if FOwnsRelatedObjectsToSheetInfo then
      if TabXFSheetInfo.RelatedObject <> nil then
        FreeAndNil(TabXFSheetInfo.RelatedObject);
    FreeAndNil(TabXFSheetInfo);
    
    CurrPage.Free;
  end;
  FActiveTabXFSheetInfo := nil;
end;

procedure TXLSPreview.Close;
begin
  if Fxf <> nil then
  begin
    ClearPages;
    FreeAndNil(Fxf);
  end;
end;

constructor TXLSPreview.Create(AParent: TWinControl; AOwnsRelatedObjectsToSheetInfo: Boolean);
var
  Owner: TComponent;
begin
  inherited create;
  FObjectList := TObjectList.Create(true);
  Owner := AParent.Owner;

  FpcXFSheets := TRzPageControl.Create(Owner);
  FObjectList.Add(FpcXFSheets);
  FpcXFSheets.Parent := AParent;
  FpcXFSheets.Align := alClient;
  FpcXFSheets.ShowFullFrame := false;
  FpcXFSheets.TabHeight := 0;
  FpcXFSheets.TabOrientation := toBottom;
  FpcXFSheets.TabStyle := tsRoundCorners;

  FpcXFSheets.OnChange := FpcXFSheetsChange;

  FPopupMenu := TPopupMenu.Create(Owner);
  FObjectList.Add(FPopupMenu);

  Fxf := nil;
  FFileName := '';
  FActiveTabXFSheetInfo := nil;

  FControlsRelatedToMenuItems := TObjectList.Create(false);

  FOwnsRelatedObjectsToSheetInfo := AOwnsRelatedObjectsToSheetInfo;
end;

destructor TXLSPreview.Destroy;
begin
  FreeAndNil(FControlsRelatedToMenuItems);
  inherited;
end;

procedure TXLSPreview.DefineSheetColumns(ATabXFSheetInfo: TTabXFSheetInfo);
var
  SheetComponPropsInfo: TSheetComponPropsInfo;
  //PropColumnsMTBoolmark: String;
  PropColumnsMTBoolmark: TBookMark;
  SheetCells: TCells;
  i: integer;
  CellValue: String;
  CellValueLen: Integer;
  ColName: String;
  ColNameLen: Integer;
  PrefLen: Integer;
  LevelNum: Integer;
begin
  if ATabXFSheetInfo.RowCount > 0 then
  begin
    SheetComponPropsInfo := TSheetComponPropsInfo(ATabXFSheetInfo.RelatedObject);

    //PropColumnsMTBoolmark := SheetComponPropsInfo.FMT.Bookmark;
    PropColumnsMTBoolmark := SheetComponPropsInfo.FMT.GetBookmark;
    SheetComponPropsInfo.FMT.DisableControls;
    try
      SheetCells := Fxf.Workbook.Sheets[ATabXFSheetInfo.SheetIndex].Cells;
      for i := 0 to ATabXFSheetInfo.ColumnCount - 1 do
      begin
        CellValue := SheetCells.Cell[0, i].ValueAsString;
        CellValueLen := Length(CellValue);
        if (CellValueLen > 2) and (Pos('[',CellValue)=1) and (Pos(']',CellValue)=CellValueLen) then
        begin
          // Определяем имя колонки
          ColName := Copy(CellValue, 2, CellValueLen - 2);
          ColNameLen := Length(ColName);
          // Если эта колонка определена в таблице
          if SheetComponPropsInfo.FMT.Locate(fnSysName, ColName, []) or
             SheetComponPropsInfo.FMT.Locate(fnSysName, tnCompPropRelation+'.'+ColName, []) then
          begin
            SheetComponPropsInfo.FMT.Edit;
            SheetComponPropsInfo.FMT.FieldByName(fnColumn).AsString := DecToABC(i+1);
            SheetComponPropsInfo.FMT.Post;
          end
          else
          begin
            if ColName = fnArticul then
              SheetComponPropsInfo.ArtNoColumIndex := i
            else
            if ColName = fnName then
              SheetComponPropsInfo.NameColumIndex := i
            else
            if ColName = fnPrice then
              SheetComponPropsInfo.PriceColumIndex := i
            else
            if ColName = fnUOM then
              SheetComponPropsInfo.IzmColumIndex := i
            else
            if Pos('LEVEL_', ColName) = 1 then
            begin
              PrefLen := Length('LEVEL_');
              LevelNum := StrToIntDef(Copy(ColName, PrefLen+1, ColNameLen - PrefLen), -1);
              if (LevelNum > 0) and (LevelNum <= SheetComponPropsInfo.StructLevelsIndex.Count) then
                SheetComponPropsInfo.StructLevelsIndex[LevelNum-1] := i;
            end;
          end;
        end;
      end;
    finally
      //SheetComponPropsInfo.FMT.Bookmark := PropColumnsMTBoolmark;
      SheetComponPropsInfo.FMT.GotoBookmark(PropColumnsMTBoolmark);
      SheetComponPropsInfo.FMT.FreeBookmark(PropColumnsMTBoolmark);
      SheetComponPropsInfo.FMT.EnableControls;
    end;
  end;
end;

procedure TXLSPreview.FpcXFSheetsChange(Sender: TObject);
var
  TabXFSheetInfo: TTabXFSheetInfo;
  TabSheet: TRzTabSheet;
  i, j: integer;
  TestStr: String;

  SheetCells: TCells;
  RangeRect: TRangeRect;
begin
  TabSheet := TRzPageControl(Sender).ActivePage;

  //*** Загрузить лист книги
  TabXFSheetInfo := nil;

  if TabSheet <> nil then
  begin
    if TabSheet.Tag <> 0 then
      TabXFSheetInfo := TTabXFSheetInfo(TabSheet.Tag);
    if TabXFSheetInfo <> nil then
    begin
      //*** Загрузить лист из Excel файла
      if TabXFSheetInfo.IsLoadedSheet = false then
      begin
        Screen.Cursor := crHourGlass;
        try
          TabXFSheetInfo.IsLoadedSheet := true;
          if Fxf.Workbook.Sheets[TabSheet.TabIndex].GetUsedRect(RangeRect) then
          begin
            TabXFSheetInfo.ColumnCount := RangeRect.ColumnTo - RangeRect.ColumnFrom + 2;
            TabXFSheetInfo.RowCount := RangeRect.RowTo - RangeRect.RowFrom + 2;
          end
          else
          begin
            //TabXFSheetInfo.ColumnCount := Fxf.Workbook.Sheets[TabSheet.TabIndex].Columns.Count;
            //TabXFSheetInfo.RowCount := Fxf.Workbook.Sheets[TabSheet.TabIndex].Rows.Count;
                                      //Fxf.Workbook.Sheets[TabSheet.TabIndex].Cells.Count
            TabXFSheetInfo.ColumnCount := Fxf.Workbook.Sheets[TabSheet.TabIndex].Cells.Count;
            TabXFSheetInfo.RowCount := TabXFSheetInfo.ColumnCount;
          end;

          //if (TabXFSheetInfo.ColumnCount <= 1) or (TabXFSheetInfo.ColumnCount > 500) then
          //  TabXFSheetInfo.ColumnCount := 500;
          //if (TabXFSheetInfo.RowCount <= 1) or (TabXFSheetInfo.RowCount > 20000) then
          //  TabXFSheetInfo.RowCount := 20000;

          //*** Количество столбцов и строк в гриде
          TabXFSheetInfo.FGrid.ColCount := TabXFSheetInfo.ColumnCount + 1;
          TabXFSheetInfo.FGrid.RowCount := TabXFSheetInfo.RowCount + 1;

          if TabXFSheetInfo.FGrid.ColCount > 1 then
            TabXFSheetInfo.FGrid.FixedCols := 1;
          if TabXFSheetInfo.FGrid.RowCount > 1 then
            TabXFSheetInfo.FGrid.FixedRows := 1;

          //*** Ширина колонок
          TabXFSheetInfo.FGrid.ColWidths[0] := 25;
          for i := 0 to TabXFSheetInfo.ColumnCount - 1 do
            TabXFSheetInfo.FGrid.ColWidths[i+1] := Fxf.Workbook.Sheets[TabSheet.TabIndex].Columns[i].WidthPx;
          //*** Высота строк
          TabXFSheetInfo.FGrid.DefaultRowHeight := 19;

          //*** Значения фиксированных столбцов, строк
          for i := 0 to TabXFSheetInfo.ColumnCount - 1 do
            TabXFSheetInfo.FGrid.Cells[i+1, 0] := DecToABC(i+1); //IntToStr(i+1);
          for i := 0 to TabXFSheetInfo.RowCount - 1 do
            TabXFSheetInfo.FGrid.Cells[0, i+1] := IntToStr(i+1);

          try
            //*** Значения ячеек
            SheetCells := Fxf.Workbook.Sheets[TabSheet.TabIndex].Cells;
            for i := 0 to TabXFSheetInfo.ColumnCount - 1 do
              for j := 0 to TabXFSheetInfo.RowCount - 1 do
              begin
                //TestStr := Fxf.Workbook.Sheets[TabSheet.TabIndex].Cells.Cell[j, i].ValueAsString;
                //Fxf.Workbook.Sheets[TabSheet.TabIndex].Cells.Cell[j, i].Value;

                //TabXFSheetInfo.FGrid.Cells[i+1, j+1] := Fxf.Workbook.Sheets[TabSheet.TabIndex].Cells.Cell[j, i].ValueAsString;
                TabXFSheetInfo.FGrid.Cells[i+1, j+1] := SheetCells.Cell[j, i].ValueAsString;
              end;
          except
          end;

          // Определить назначение столбцов по кодам первой строки
          DefineSheetColumns(TabXFSheetInfo);
        finally
          Screen.Cursor := crDefault;
        end;
      end;
    end;
  end;

  FActiveTabXFSheetInfo := TabXFSheetInfo;

  if Assigned(FOnChangeSheet) then
    FOnChangeSheet(TabXFSheetInfo);
end;

procedure TXLSPreview.FPopupMenuItemClick(Sender: TObject);
var
  CursorCol: Integer;
  CursorRow: Integer;
begin
  if FActiveTabXFSheetInfo <> nil then
  begin
    FActiveTabXFSheetInfo.FGrid.MouseToCell(FXFSheetPopupPoint.X, FXFSheetPopupPoint.Y, CursorCol, CursorRow);

    FActiveTabXFSheetInfo.ColumnContextPopup := CursorCol;
    FActiveTabXFSheetInfo.RowContextPopup := CursorRow;

    if Assigned(FOnMenuItemClick) then
      FOnMenuItemClick(Sender);
  end;
end;

function TXLSPreview.OpenFromFile(AFileName: string): Boolean;
begin
  Result := false;

  Close;

  Fxf := TXLSFile.Create;
  try
    Fxf.OpenFile(AFileName);
    Result := true;
    FFileName := AFileName;
  except
    on E: Exception do
    begin
      Result := false;
      Close;
    end;
  end;
end;

procedure TXLSPreview.ShowXLS;
var
  NewTabSheet: TRzTabSheet;
  NewTabXFSheetInfo: TTabXFSheetInfo;
  i: Integer;
begin
  ClearPages;
                                                  //Fxf.Workbook.Sheets[i].Columns[0].
  for i := 0 to Fxf.Workbook.Sheets.Count - 1 do
  begin
    NewTabSheet := TRzTabSheet.Create(nil);
    NewTabSheet.PageControl := FpcXFSheets;
    NewTabSheet.Caption := Fxf.Workbook.Sheets[i].Name;

    NewTabXFSheetInfo := TTabXFSheetInfo.Create(NewTabSheet);
    NewTabXFSheetInfo.SheetIndex := i;
    NewTabXFSheetInfo.FGrid.PopupMenu := FPopupMenu;
    NewTabXFSheetInfo.FGrid.OnContextPopup := XFSheetContextPopup;
    NewTabSheet.Tag := Integer(NewTabXFSheetInfo);

    if Assigned(FOnCreateSheetInfo) then
      FOnCreateSheetInfo(NewTabXFSheetInfo);
  end;
  if FpcXFSheets.PageCount > 0 then
    FpcXFSheets.ActivePage := FpcXFSheets.Pages[0];
end;

procedure TXLSPreview.XFSheetContextPopup(Sender: TObject;
  MousePos: TPoint; var Handled: Boolean);
begin
  FXFSheetPopupPoint := MousePos;
end;


function GetComponentType(ComboBox_ComponentType: TcxComboBox): TComponentType;
var
  SprComponentType: TNBComponentType;
begin
  Result.ID := 0;
  Result.NAME := '';
  Result.NamePlural := '';
  Result.PortKind := pkNone;
  Result.ActiveState := biFalse;
  Result.IsLine := biFalse;
  Result.IsStandart := biFalse;
  if ComboBox_ComponentType.Text <> '' then
  begin
     Result := F_NormBase.DM.GetComponentType(GetIDFromComboBox(ComboBox_ComponentType));
  end;
end;

{ TSheetComponPropsInfo }

constructor TSheetComponPropsInfo.Create;
var
  i: Integer;
  CompType: TComponentType;
  NBCompType: TNBComponentType;
  NormBaseProperty: TNBProperty;
begin
  inherited;
  ArtNoColumIndex := -1;
  PriceColumIndex := -1;
  NameColumIndex := -1;
  IzmColumIndex := -1;
  ArtNoType := antProduc;

  NormResCypherColumIndex := -1;
  NormResNameColumIndex := -1;
  NormResIzmColumIndex := -1;
  ResPriceColumIndex := -1;
  ResTypeColumIndex := -1;

  StructLevelsIndex := TIntList.Create;
  for i := 0 to cntStructLevels - 1 do
    StructLevelsIndex.Add(-1);

  FMT := TkbmMemTable.Create(nil);
  FMT.FieldDefs.Add(fnSysName, ftString, 255);
  FMT.FieldDefs.Add(fnCaption, ftString, 255);
  FMT.FieldDefs.Add(fnColumn, ftString, 255);
  FMT.FieldDefs.Add(fnColumnNum, ftInteger);

  FMT.Active := true;
  AddRowToMT(fnComponentType, cComponentType);
  AddRowToMT(fnSuppliesKindName, cSuppliesKindNameB); // Наименование поставки
  AddRowToMT(fnSuppliesKindUnitKolvo, cSuppliesKindUnitKolvo); // Количество в поставке
  AddRowToMT(fnIsPriceForSuppliesKind, cIsPriceForSuppliesKind); //23.11.2011 Цена за поставку
  //AddRowToMT('SUPPLIES_KIND_UNIT_PRICE', ''); // Стоимость поставки
  AddRowToMT(fnSign, cNameShortB);
  //AddRowToMT(fnUOM, cSCSComponent_Msg6_3);

  {$IF Not Defined (FINAL_SCS) or Defined(BASEADM_SCS)}
    AddRowToMT(fnObjectIcon, 'УГО');
    AddRowToMT(fnObjectIconDesign, 'УГО для дизайна');

    // ЭКК
    for i := 1 to 20 do
      AddRowToMT('CE_'+IntToStr(i), 'ЭКК '+IntToStr(i));
  {$IFEND}

  AddCompPropToMT(pnCategory);
  AddCompPropToMT(pnColor);
  AddCompPropToMT(pnHeight);
  AddCompPropToMT(pnHeightInUnits);
  AddCompPropToMT(pnLength);
  AddCompPropToMT(pnMaxComplectCount);
  AddCompPropToMT(pnMultimode);
  AddCompPropToMT(pnOutDiametr);
  AddCompPropToMT(pnOutSection); // внешнее сечение, мм2
  AddCompPropToMT(pnPortCount);
  AddCompPropToMT(pnPortWireCount);
  AddCompPropToMT(pnShield);
  AddCompPropToMT(pnWidth);
  AddCompPropToMT(pnWireCount);
  {$IF Not Defined (FINAL_SCS)  or Defined(BASEADM_SCS) }
    AddCompPropToMT(pnSectionSize);
    AddCompPropToMT(pnInSection);
    AddCompPropToMT(pnCableChannelSideSection);
    AddCompPropToMT(pnConduitSideDimensions);
    AddCompPropToMT(pnConduitElmentSideDimensions);
    AddCompPropToMT(pnConduitElmentSide1Dimensions);
    AddCompPropToMT(pnConduitElmentSide2Dimensions);
    AddCompPropToMT(pnConduitElmentSide3Dimensions);
    AddCompPropToMT(pnConduitElmentSide4Dimensions);
    AddCompPropToMT(pnAngle);
    AddCompPropToMT(pnCableCanalElemetType);
  {$IFEND}

  // Интерфейсы
  for i := 1 to 2 do
    AddRowToMT(fnInterf+'_'+IntToStr(i), cNameInterfaceB+'_'+IntToStr(i));

  //FMT.FieldDefs.Add(fnDescription, ftString, 2000);
  //FMT.FieldDefs.Add('IMAGE', ftString, 500);
  // Tolik 10/05/2018 --
  (*
  {$IF Defined(SCS_PE)}
    AddRowToMT(fnDescription, 'Description');
    AddRowToMT('IMAGE', 'Image');
  {$ELSE}
    AddRowToMT(fnDescription, 'Описание');
    AddRowToMT('IMAGE', 'Изображение');
  {$IFEND}
  *)
  AddRowToMT(fnDescription, cDescriptionMess);
  AddRowToMT('IMAGE',  cImageMess);
  //
  if F_NormBase.F_MasterUpdatePrice.cbLoadFromCompType.Checked then
  begin
    CompType := GetComponentType(F_NormBase.F_MasterUpdatePrice.ComboCompType);
    if CompType.SysName <> '' then
    begin
      FMT.First;
      NBCompType := F_NormBase.GSCSBase.NBSpravochnik.GetComponentTypeByGUID(CompType.GUID);
      for i := 0 to NBCompType.Properties.Count - 1 do
      begin
        NormBaseProperty := F_NormBase.GSCSBase.NBSpravochnik.GetPropertyByGUID(TNBCompTypeProperty(NBCompType.Properties[i]).PropertyData.GUIDProperty);
        if not FMT.Locate(fnSysName, tnCompPropRelation+ '.'+ NormBaseProperty.PropertyData.SysName, []) then
          AddRowToMT(tnCompPropRelation+ '.'+ NormBaseProperty.PropertyData.SysName, NormBaseProperty.PropertyData.Name);
      end;
    end;
  end;

  FDataSource := TDataSource.Create(nil);
  FDataSource.DataSet := FMT;
end;

procedure TSheetComponPropsInfo.AddRowToMT(const ASysName, ACaption: String; AColumn: String='');
begin
  FMT.Append;
  FMT.FieldByName(fnSysName).AsString := AnsiUpperCase(ASysName);
  FMT.FieldByName(fnCaption).AsString := ACaption;
  FMT.FieldByName(fnColumn).AsString := AColumn;
  FMT.Post;
end;

procedure TSheetComponPropsInfo.AddCompPropToMT(const APropSysName: String);
var
  NBProperty: TNBProperty;
  PropName: String;
begin
  NBProperty := F_NormBase.GSCSBase.NBSpravochnik.GetPropertyBySysName(APropSysName);
  PropName := '';
  if NBProperty <> nil then
    PropName := NBProperty.PropertyData.Name
  else
    PropName := APropSysName;
  AddRowToMT(tnCompPropRelation+'.'+APropSysName, cNamePropertyB+' '+PropName);
end;

procedure TF_MasterUpdatePrice.lvExistsObjectsSelectItem(Sender: TObject;
  Item: TListItem; Selected: Boolean);
begin
  if Selected then
    if Item <> nil then
      if FFromForm = TF_Main(GForm).F_CaseForm then
      begin
        TF_Main(GForm).F_CaseForm.LocateItemByID(Integer(Item.Data));
      end;
end;

procedure TF_MasterUpdatePrice.tvComponentsCloseUp(
  Sender: TISPlugInplaceEdit; Section: TISPlugSection;
  DropDown: TISDropDown; var Accept: Boolean);
var
  SelectedNodeInCombo: TFlyNode;
  NodeObjInfo: TNodeObjectInfo;
begin
  // получаем выбранную ветвь из комбаря
  SelectedNodeInCombo := GetTreeViewSelectedNodeInComboOnClose(tvComponents, DropDown);
  if SelectedNodeInCombo <> nil then
  begin
    NodeObjInfo := TNodeObjectInfo(tvComponents.Selected.Data);
    if NodeObjInfo <> nil then
      case FFormMode of
        fmImportResources:
          NodeObjInfo.ResType := Integer(SelectedNodeInCombo.Data);
      end;
  end;
end;

procedure TF_MasterUpdatePrice.pmiSetColAsIzmClick(Sender: TObject);
begin
  //
end;

destructor TSheetComponPropsInfo.Destroy;
begin
  StructLevelsIndex.Free;
  FMT.Active := false;
  FMT.Free;
  FDataSource.Free;

  inherited;
end;

procedure TSheetComponPropsInfo.DefineColumnsNums;
var
  //BookMarkStr: String;
  BookMarkStr: TBookMark;
  CurrCol: String;
  CurrColNum: Integer;
begin
  //BookMarkStr := FMT.Bookmark;
  BookMarkStr := FMT.GetBookmark;
  FMT.DisableControls;
  try
    FMT.First;
    while Not FMT.Eof do
    begin
      CurrColNum := -1;
      CurrCol := FMT.FieldByName(fnColumn).AsString;
      if CurrCol <> '' then
      begin
        FMT.Edit;
        FMT.FieldByName(fnColumnNum).AsInteger := ABCToDec(CurrCol); //ABCToDec(CurrCol) - 1;
        FMT.Post;
      end;
      FMT.Next;
    end;
  finally
    FMT.EnableControls;
    //FMT.Bookmark := BookMarkStr;
    FMT.GotoBookmark(BookMarkStr);
    FMT.FreeBookmark(BookMarkStr);
  end;
end;

procedure TF_MasterUpdatePrice.GT_PropColumnsColumnPropertiesValidate(
  Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
  var Error: Boolean);
begin
  TcxComboBoxProperties(GT_PropColumnsColumn.Properties).OnValidate := nil;
  try
    FActiveSheetComponPropsInfo.FMT.Edit;
    FActiveSheetComponPropsInfo.FMT.FieldByName(fnColumn).AsString := DisplayValue;
    FActiveSheetComponPropsInfo.FMT.Post;
  finally
    TcxComboBoxProperties(GT_PropColumnsColumn.Properties).OnValidate := GT_PropColumnsColumnPropertiesValidate;
  end;
end;

procedure TF_MasterUpdatePrice.cbLoadFromCompTypeClick(Sender: TObject);
begin
  ComboCompType.Enabled := cbLoadFromCompType.Checked;
  if ComboCompType.Enabled then
  begin
    FillComboBox(ComboCompType, F_NormBase, True, tnComponentTypes, fnID, fnName, '', 0);
  end;
end;

procedure TF_MasterUpdatePrice.fsComponCountLackDblClick(Sender: TObject);
begin
  NoFindedArticles.SaveToFile('c:\No_Finded.txt');
  showmessage('Saved to c:\No_Finded.txt');
end;

procedure TF_MasterUpdatePrice.fsComponCountExistsDblClick(
  Sender: TObject);
begin
  FindedArticles.SaveToFile('c:\Finded.txt');
  showmessage('Saved to c:\Finded.txt');
end;

end.
