/
YakuninAV
/
Convertors
Обзор
Документация
Войти
/
YakuninAV
/
Convertors
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
RDB2/RDB2_Types.pas
2 646 строк
90 KB
YakuninAV
begin with gitflick
31 июл 2026, 15:21
31 июл 2026, 15:21
1dc0fc6
Код
Авторство
О чём код?
unit RDB2_Types; {$I mormot.defines.inc} interface uses {$IFDEF ISDELPHIXE2} System.SysUtils, System.Classes, System.Variants, {$ELSE} SysUtils, Classes, Variants, {$ENDIF} mormot.core.base, mormot.core.variants, mormot.core.unicode, mormot.core.text, mormot.core.data, mormot.core.datetime, DBDCommons, DBDStrUtils, DBDWindows , dbdutf8utils , EstTypes ,{$IFDEF FPC} EstRusStringsU {$ELSE} EstRusStringsA{$ENDIF} ,{$IFDEF ISDELPHIXE2} RDB2_TLB_XE, {$ELSE} RDB2_TLB, {$ENDIF} RDB2_Protect ; {$IFDEF FPC} type TString1251 = Type String(1251); {$ENDIF} const { Some TypeNames } /// Наименование типа сметного документа EstDocTypeName = 'EST_DOCUMENT'; /// ManDocTypeName = 'MARKET_ANALYSIS'; /// VolDocTypeName = 'BILL_WORKVOLUMES'; /// BWVDocTypeName = 'BILL_WORKVOLUMES'; /// Наименование типа стандарной книги EstStdBookTypeName = 'StdEstBook'; /// M29DocTypeName = 'M29'; /// CompDocTypeName = 'EST_COMPENSATION'; /// Наименование типа документа объектных смет ObjDocTypeName = 'OBJECT_ESTIMATE'; /// ConDocTypeName = 'CONSOLIDATED_ESTIMATE'; /// ExportIDTypeName = 'LIST_EXPORTID'; ServiceBookTypeName='SERVICE_BOOK'; MarketAnalisysTypeName='MARKET_ANALISYS'; /// Неверный хендл файла-документа InvalidDocHandle = -1; var ParamsListSeparator: RawUtf8 = ','; var RDB_MAX_VALUE_PRECISION: Integer; jnCellValue, jnCellFormula, jnCellPrecision, jnItemName: RawUtf8; const /// Уровни строк (слоёв) таблицы /// Уровень размещения строк с данными RDB2_LEVEL_ITEM=0; /// Уровень размещения строк с итогами RDB2_LEVEL_TOTAL=1; /// Уровень размещения строк с заголовками структуры RDB2_LEVEL_SECT=-1; /// Уровень, на котором размещается конец раздела/документа RDB2_LEVEL_EOD=-2; RDB2_LEVEL_EOF=-2; // deprecated RDB2_SECTION_DEEPNESS=0; RDB2_SUBSECTION_DEEPNESS=1; /// Строка не является валидной JSON-строкой rdb2InvalidJSON = 9999999; rdb2UncorrecrJSON = 9999998; rdb2EmptyJSON = 9999997; rdb2InvalidFile = 9999996; rdb2FileNotExists = 9999995; rdb2EmpyFileName = 9999994; rdb2NotConnected = 9999993; rdb2EmptyFile = 9999992; rbd2InvalidFileName = 9999991; rdb2EmptyAuthor = 9999990; rdb2InvalidAuthor = 9999989; {Object Declarations} /// Количество элементов объектной сметы ObjValCount = 6; var /// Идентификатор для объединённой графы объектной сметы ObjAllColsId: RawByteString; /// Идентификаторы полей записей объектной сметы ObjValFields: array[0..ObjValCount-1] of RawByteString; /// Идентификаторы граф объектной сметы ObjValIds: array[0..ObjValCount-1] of RawByteString; /// Идентификаторы наименований граф объектной сметы ObjValCaptions: array[0..ObjValCount-1] of RawByteString; const {RDB Cell types} clt_Count = 5; clt_Variant = -1; clt_String = 0; clt_File = 1; clt_Calc = 2; clt_DateTime = 3; clt_Strings = 4; clt_Array = 5; clt_Empty = -999; // пустая клетка {Cell Array Types} cat_String = 0; {Calc states} ct_Constant = 0; ct_Formula = 1; ct_Text = 2; ct_List = 3; {DataBase Locations} dbl_Auto = 0; dbl_HardDisk = 1; dbl_Memory = 2; {Access Modes} amd_Read = 1; amd_ReadWrite = 3; {Errors} err_OK = 0; err_DiskSpaceOut = 1; {Search flags} scf_UpCase = 1; scf_DelSpace = 2; scf_Full = 4; scf_Begin = 8; scf_OR = 16; scf_NOT = 32; scf_FullWord = 64; scf_ByMask = 128; scf_SpecZeroFilter = 256; scf_InCustomStr = 512; scf_InText = 1024; scf_FilterDelims = 2048; {Complex doc flags} cdf_Linked = 1; cdf_Embedded = 2; cdf_Divisions = 4; {Compression const's} ccm_None = 0; ccm_Deflate = 1; ccld_None = 0; ccld_Fast = 1; ccld_Default = 2; ccld_Best = 3; {EstDocument flags} edf_CheckReport = 1; {Compensation line dets} MehResDet = 3; MatResDet = 4; {United compensation sort modes} ucsm_ByQuota = 1; ucsm_ByValue = 2; ucsm_ByAlphabet = 3; ucsm_ByCode = 4; {Query view modes} qvm_Flat = 0; qvm_Struc = 1; {Cursor copy flags} ccf_NotSrcEmpty = 1; ccf_DestEmpty = 2; {cell separator} cs_DefaultDelim = #4; cs_StdSeparator = #7; const MusorGroupsCount= 3; MusorGroupNames : array[0..MusorGroupsCount-1] of string = ('GZK','GSM','MUS'); MusorNames : array[0..MusorGroupsCount-1] of string = ('Вывоз грунта из под зданий и коммуникаций', 'Вывоз грунта слежавшегося, с содержанием строительного мусора', 'Вывоз строительного мусора'); MusorUnions : array[0..MusorGroupsCount-1] of string =('м3','м3','т'); MusorCodePrefix='MUSOR:'; type PRDBRebaseInfo = ^TRDBRebaseInfo; TRDBRebaseInfo = record public SecTotalsOldBase: Integer; SecTotalsLinesCount: Integer; SecTotalsNewBase: Integer; EstTotalsOldBase: Integer; EstTotalsLinesCount: Integer; EstTotalsNewBase: Integer; procedure Clear; procedure Init(const Base, Count: Integer; const Est: Boolean=False); function isReady(const Est: Boolean=False): Boolean; function IsInit(const Est: Boolean=False): Boolean; end; TRDBSysParam = packed record ID: RawUtf8; Value: RawUtf8; end; TRDBSysParamDynArray = array of TRDBSysParam; TRDBEmbeddedItem = record private FDescription: RawUtf8; FFilePath: RawUtf8; FID: RawUtf8; FItemType: RawUtf8; FName: RawUtf8; FModified: TDateTime; FSize: Cardinal; FFlag: Integer; function GetEmpty: Boolean; procedure SetDescription(const Value: RawUtf8); procedure SetEmpty(const Value: Boolean); procedure SetFilePath(const Value: RawUtf8); procedure SetFlag(const Value: Integer); procedure SetID(const Value: RawUtf8); procedure SetItemType(const Value: RawUtf8); procedure SetModified(const Value: TDateTime); procedure SetName(const Value: RawUtf8); procedure SetSize(const Value: Cardinal); public property ID: RawUtf8 read FID write SetID; property Name: RawUtf8 read FName write SetName; property Modified: TDateTime read FModified write SetModified; property Description: RawUtf8 read FDescription write SetDescription; property ItemType: RawUtf8 read FItemType write SetItemType; property Size: Cardinal read FSize write SetSize; property FilePath: RawUtf8 read FFilePath write SetFilePath; property FLag: Integer read FFlag write SetFlag; property Empty: Boolean read GetEmpty write SetEmpty; procedure Clear; function FromDoc(P: PDocVariantData): Boolean; function ToDoc: Variant; end; TRDBEmbeddedItemDynArray = array of TRDBEmbeddedItem; PRDBEmbeddedItem = ^TRDBEmbeddedItem; TRDBTableRow = record function GetFieldAsString(Name: RawUtf8): string; overload; inline; function GetFieldAsUtf8(Name: RawUtf8): RawUtf8; overload; inline; function GetFieldAsVariant(Name: RawUtf8): Variant; overload; inline; public Data: Variant; property S[Name: RawUtf8]: string read GetFieldAsString; property U[Name: RawUtf8]: RawUtf8 read GetFieldAsUtf8; property V[Name: RawUtf8]: Variant read GetFieldAsVariant; class function GetFieldAsString(const pData: PDocVariantData; const Name: RawUtf8): string; overload; static; class function GetFieldAsUtf8(const pData: PDocVariantData; const Name: RawUtf8): RawUtf8; overload; static; class function GetFieldAsVariant(const pData: PDocVariantData; const Name: RawUtf8): Variant; overload; static; end; /// Запись с данными ячейки таблицы RDB TRDBCellValue = record private FValue: RawUTF8; FData: PDocVariantData; function GetAsCurrency: Currency; function GetFormula: string; function GetPrec: Integer; function GetValue: string; procedure SetAsCurrency(NewValue: Currency); procedure SetFormula(NewValue: string); procedure SetValue(NewValue: string); procedure SetPrec(NewValue: Integer); public property Formula: string read GetFormula write SetFormula; property Prec: Integer read GetPrec; property Value: string read GetValue; constructor Create(P: PDocVariantData; const Name: RawUTF8=''); function FromDocVariant(P: PDocVariantData; const Name: RawUTF8=''): Boolean; property AsCurrency: Currency read GetAsCurrency write SetAsCurrency; function AsDouble: Double; function AsInteger: Integer; function AsString: string; function AsUTF8: RawUTF8; function isString: Boolean; function isValid: Boolean; function isZero: Boolean; function isEmpty: Boolean; function isOne: Boolean; function isValidCoef: Boolean; end; /// Вид книги (ClassName) // rdbBCStdEstBook - стандартная книга // rdbBCEstDocument - сметный документ // rdbBCObjDocument - объектная смета // rdbBCSumDocument - сводная смета // rdbBCMarketAnalisys - конъюктурный анализ // rdbBCVolumesList - ведомость объёмов TRDBBookClass = (rdbBCStdEstBook, rdbBCEstDocument, rdbBCObjDocument, rdbBCSumDocument, rdbBCMarketAnalisys, rdbBCVolumesList, rbdBCUnknown); /// Набор видов книг TRDBBookClasses = set of TRDBBookClass; /// Тип книги // rdbBTEstDocument - Смета EST_DOCUMENT // rdbBTObjEstimate - Объектная смета OBJECT_ESTIMATE // rdbBTSumEstimate - Сводная смета CONSOLIDATED_ESTIMATE // rdbBTMarketAnalisys - конъюктурный анализ MARKET_ANALYSIS // rdbBTVolumesList - ведомость объёмов BILL_WORKVOLUMES // rdbBTService - Улуги SERVICE_BOOK // rdbBTResources - Ресурсы // rdbBTPriceBook - Расценки PRICE_BOOK // rdbBTPriceList - Ценник PRICE_LIST // rdbBTMachines - Цены на эксплуатацию машин MECH_BOOK // rdbBTLabour - Тарифы TRUD_BOOK // rdbBTESNBook - ЕСН ESN_BOOK // rdbBTTransport - Цены на перевозку TRANS_BOOK // rdbBTInflation - Индексы инфляции FACTOR_BOOK // rdbBTResurcesGESN- Ценники ГЭСН (текущие цены) FACTOR_BOOK // rdbBTOverdraft - Нормативы накладных расходов NR_BOOK // rdbBTProfit - Нормативы сметной прибыли PN_BOOK // rdbBTCorrections - Поправочные коэффициенты CORRECTION_BOOK // rdbBTDismantling - Поправочные коэффициенты на демонтаж DEMONTAJ_BOOK // rdbBTUndefined - неопределено TRDBBookType = (rdbBTEstDocument, rdbBTObjEstimate, rdbBTSumEstimate, rdbBTMarketAnalisys, rdbBTVolumesList, rdbBTResources, rdbBTPriceBook, rdbBTPriceList, rdbBTMachines, rdbBTLabour, rdbBTTransport, rdbBTInflation, rdbBTResurcesGESN, rdbBTOverdraft, rdbBTProfit, rdbBTESNBook, rdbBTCorrections, rdbBTDismantling, rdbBTService, rdbBTUndefined); /// Набор типов книг TRDBBookTypes = set of TRDBBookType; /// Авторы методик расчёта смет /// Методика ФЕР /// Методика ТСН /// Методика ГЭСН TRDBMethodicAuthor = (rdbMAFER, rdbMAMNB, rdbMAGSN, rdbMAUndefine); TRDBMethodicAuthors = set of TRDBMethodicAuthor; const RDBResourceBookTypes: TRDBBookTypes = [rdbBTPriceList, rdbBTMachines, rdbBTTransport, rdbBTLabour, rdbBTResources]; RDBEsnBookTypes: TRDBBookTypes = [rdbBTESNBook]; RDBGesnBookTypes: TRDBBookTypes = [rdbBTResurcesGESN]; RDBIndexBookTypes: TRDBBookTypes = [rdbBTInflation]; RDBOPBookTypes: TRDBBookTypes = [rdbBTOverdraft, rdbBTProfit]; RDBEstimateBookTypes: TRDBBookTypes = [rdbBTEstDocument, rdbBTObjEstimate, rdbBTSumEstimate]; RDBCorrectionsBookTypes: TRDBBookTypes = [rdbBTCorrections]; RDBDismantlingBookTypes: TRDBBookTypes = [rdbBTDismantling]; RDBOtherBookTypes: TRDBBookTypes = [rdbBTService]; type /// Описание значения поля TFieldDescriptor=packed record Name: string; What: integer; Prec: integer; Default: string; end; TFieldsInfo= array of TFieldDescriptor; PDocHeader= ^TDocHeader; /// Заголовок файла-документа { TDocHeader } TDocHeader = packed record ID: string[24]; ProjName: string[12]; ServerName: string[12]; ClassName: string[24]; CompressionMethod, CompressionLevel: Byte; BlobPos, UncompressedSize, TotalSize: Cardinal; //unsigned 32-bit DriverLogVer: Byte; DocFlags: Byte; TypeName: string[24]; ShortName: string[24]; Name: string[80]; FormatVer: LongInt; //signed 32-bit Region: string[36]; Author: string[24]; AuthorName: string[36]; DataLevel: TDate; Coauthors: string[36]; DataMask: string[99]; SerialNumber: LongInt; ServiceFlag: Byte; MacroFlag: Byte; MacroPassword: string[8]; KeyMask: array[0..7] of Cardinal; //0..255 битовые флаги, соответсвтуют номерам 1..256 NetMask: array[0..7] of Word; //8 пар байтов описывают 8 сетевых ключей: 1-й байт - номер, 2-й байт - мощность //unsigned 16-bit Password: string[23]; DriverID: string[7]; SourceID: string[31]; Edition: Byte; Version: Byte; RegionID: string[35]; private function GetBaseMethodic: TEstimateBaseMethodic; function GetBookClass: TRDBBookClass; inline; procedure SetBookClass(const Value: TRDBBookClass); inline; function GetBookType: TRDBBookType; procedure SetBookType(const Value: TRDBBookType); public property BaseMethodic: TEstimateBaseMethodic read GetBaseMethodic; /// Вид книги property BookClass: TRDBBookClass read GetBookClass write SetBookClass; property BookType: TRDBBookType read GetBookType write SetBookType; // class function GetDocHeader(Stream: TStream; Code: boolean; FromBegin:boolean=true): TDocHeader; static; constructor CreateEstDocument(const Methodic: string); function GetAuthor: RawByteString; function GetAuthorName: RawByteString; function GetPassword: string; function GetRegion: RawByteString; function GetShortName: RawByteString; function ToDoc: Variant; end; TDocHeaders = array of TDocHeader; /// Буфер вмещающий заголовок файла-документа THeaderBuf=array[1..256] of integer; const /// Количество байт занимаемых заголовком файла-документа dhSize = SizeOf(TDocHeader); /// Минимальное количество корневых элементов (таблиц)в JSON-документе формата TS RDBEswDocRootItemsCount = 16; var RDBFieldValueName, RDBFieldFormulaName, RDBFieldPrecisionName, RDBItemSectionNameU, RDBItemPositionNameU, RDBItemCreditNameU: RawUTF8; RDBFieldsSeparator: string; RDBResNameLabour, RDBUnResNameLabour, RDBResNameMaterial, RDBUnResNameMaterial, RDBResNameMachines, RDBUnResNameMachines, RDBResEquipmnt: RawUTF8; RDBEstDocTblHeaderName, RDBEstDocTblSysTable, RDBEstDocTblUserTable, RDBEstDocTblResourceTable, RDBEstDocTblEsnTable, RDBEstDocTblMethodicTable, RDBEstDocTblVariables, RDBEstDocTblActTable, RDBEstDocTblParameters, RDBEstDocTblCommands, RDBEstDocTblResources, RDBEstDocTblConstructions, RDBEstDocTblVolumes, RDBEstDocTblGFactors, RDBEstDocTblRequisites, RDBEstDocTblMainTable: string; RDBEstDocTblHeaderNameU, RDBEstDocTblSysTableU, RDBEstDocTblUserTableU, RDBEstDocTblResourceTableU, RDBEstDocTblEsnTableU, RDBEstDocTblMethodicTableU, RDBEstDocTblVariablesU, RDBEstDocTblActTableU, RDBEstDocTblParametersU, RDBEstDocTblCommandsU, RDBEstDocTblResourcesU, RDBEstDocTblConstructionsU, RDBEstDocTblVolumesU, RDBEstDocTblGFactorsU, RDBEstDocTblRequisitesU, RDBEstDocTblMainTableU: RawUTF8; var /// Имя элемента JSON, содержащего название файла-шаблона для формирования сметы в формате Турбосметчика TmpltJName: RawUTF8; /// Имя элемента JSON, содержащего название папки, содержащий справочники Турбосметчика BooksJName: RawUTF8; /// Имя элемента JSON, содержащего название файла, содержащего справочник нормативов накладных расходов OverdraftJName: RawUTF8; /// Имя элемента JSON, содержащего название файла, содержащего справочник нормативов сметной прибыли ProfitJName: RawUTF8; type // Formulas TAgrFunction = packed record ID,Tab,Lev,Col: integer; end; TReference = packed record Tab,Lev,Num,Col : integer; end; //-------------end /// Состояние JSON-документа // rdbEDSNew - новый // rdbEDSModified - модифицирован // rdbEDSReaded - прочитан из файла // rdbEDSEmpty - пустой JSON-документ // TRDBEstDocumentState = (rdbEDSNew, rdbEDSModified, rdbEDSReaded, rdbEDSOpened, rdbEDSEmpty); /// Запись для хранения информации о полях таблицы RDB2 TRDBFieldInfo = record Names, Values, Formulas: TRawUTF8DynArray; Precisions, FieldTypes: TIntegerDynArray; private function GetCount: Word; function GetFormula(Index: integer): string; function GetIsResource(Index: integer): Boolean; function GetName(Index: integer): string; function GetPrecision(Index: integer): Integer; function GetValue(Index: integer): string; procedure SetCount(const Value: Word); procedure SetFormula(Index: integer; const Value: string); procedure SetName(Index: integer; const Value: string); procedure SetPrecision(Index: integer; const Value: Integer); procedure SetValue(Index: integer; const Value: string); function GetField(Index: integer): Variant; function GetFieldType(Index: integer): Integer; procedure SetFieldType(Index: integer; const Value: Integer); function GetNameUtf8(Index: integer): RawUtf8; procedure SetNameUtf8(Index: integer; const Value: RawUtf8); public /// Наименование поля property Name[Index: integer]: string read GetName write SetName; /// Наименование поля property NameUtf8[Index: integer]: RawUtf8 read GetNameUtf8 write SetNameUtf8; /// Значение хранимое в поле property Value[Index: integer]: string read GetValue write SetValue; /// Формула для расчёта значения property Formula[Index: integer]: string read GetFormula write SetFormula; /// Точность представления вещественного значения property Precision[Index: integer]: Integer read GetPrecision write SetPrecision; /// Тип поля property FieldType[Index: integer]: Integer read GetFieldType write SetFieldType; /// Ячейка таблицы, предсьтавленная JSON-документом property Field[Index: integer]: Variant read GetField; /// Тип поля property IsResource[Index: integer]: Boolean read GetIsResource; /// Количество полей property Count: Word read GetCount write SetCount; /// Процедура очищает информацию procedure Clear; /// Функция возвращает индекс поля по его названию function FieldIndexByNameU(const FieldName: RawUtf8): Integer; /// Функция возвращает индекс поля по его названию function FieldIndexByNameS(const FieldName: string): Integer; /// Функция возвращает true если всё в порядке function isValid: Boolean; /// Функция возвращает true если пусто function isEmpty: Boolean; /// Функция преобразовывает текстовое значение в Variant class function StringToVariant(const aValue: RawUTF8; const afldTyp: Integer): Variant; static; /// Функция перекодирует массив строк в массив UTF8-строк class function StrToUTF8(Src: TStringDynArray; Dst: TRawUTF8DynArray): Boolean; static; /// Функция возвращает true, если имя поля соответствует имени поля, содержащего описание ресурса class function IsResourceField(const FieldName: RawUTF8): Boolean; static; /// Функция формирует JSON-документ с инормацией function ToDoc: Variant; end; /// Массив записей с информацией о полях таблицы RDB2 TRDBFieldInfoArray = array of TRDBFieldInfo; /// Указатель на запись с информацией о полях таблицы RDB2 PRDBFieldInfo = ^TRDBFieldInfo; /// Запись, содержащая информацию о ресурсе //Формат: Шифр#Наименование#Ед.изм.#Цена#Факт.объём#Цена факт. =Расход // (Cypher#Name#Ed#NormPrice#FactVol#FactPrice=Value) TRDBResourceItem=record /// Шифр ресурса Cypher: RawUtf8; /// Наименование ресурса Name: RawUtf8; /// Единица измерения расхода ресурса Ed: RawUtf8; /// Строимость ресурса из сборника цен NormPrice: Currency; /// Фактический объём израсходованного ресурса FactVol: Double; /// Фактическая стоимость израсходованного ресурса FactPrice: Currency; /// Расход ресурса на единицу объёма расценки в которую входит ресурс Consumption: Double; /// Тип ресурса ResType: TRDBBookType; /// Строка с ресурсом из ТС Data: RawUTF8; /// Идентификатор индекса пересчёта в текущие цены для ресурсов из файла ФГИСЦС FgiscsIndexID: Integer; /// Значение индекса пересчёта в текущие цены из файла ФГИСЦС FgiscsIndexValue: Double; /// абстрактный ресурс (расход по проекту - Value='П') UnAccounted: Boolean; CodeOKP: RawUtf8; CodeOKPD2: RawUtf8; /// Конструктор инициализирует запись constructor Create(const rt: TRDBBookType; const S: RawUtf8); /// Процедура очищает запись procedure Clear; procedure FromJSON(const P: PDocVariantData); /// Процедура инициализирует запись информацией из строки с описанием ресурса procedure FromRawUTF8(const R: RawUtf8); //inline; /// Процедура инициализирует запись информацией из строки с описанием ресурса procedure FromString(const S: string); /// Функция формирует строку с описанием ресурса function ToRawUTF8: RawUTF8; inline; /// Функция формирует строку с описанием ресурса function ToString: string; end; /// Массив записей с информацией о ресурсах TRDBResourceItems = array of TRDBResourceItem; /// Массив записей с информацией о ресурсах TRDBResourceItemDynArray = array of TRDBResourceItem; /// Указатель на запись с информацией о ресурсе PRDBResourceItem = ^TRDBResourceItem; /// Запись для обработки нортативов для расценки (NRMV/CPV) // PZ,ZP,EM,ZPM,MAT,PROCH,VOZVRAT,ZT,ZTMECH,MUSOR,OMASS,GRUNT,NETTO,BRUTTO,,Loaded TRDBNorms = record private FTxt: RawUtf8; arTxt: TRawUtf8DynArray; arValues: TDoubleDynArray; FCapacity: Integer; function _Get(const Idx: Integer): Double; inline; procedure _Set(const Idx: Integer; const Value: Double); inline; function GetDirect: Currency; function GetStartupLoaded: Double; procedure SetDirect(const Value: Currency); procedure SetStartupLoaded(const Value: Double); function GetMachines: Currency; function GetMachinistSalary: Currency; function GetWorkerSalary: Currency; procedure SetMachines(const Value: Currency); procedure SetMachinistSalary(const Value: Currency); procedure SetWorkerSalary(const Value: Currency); function GetMaterial: Currency; procedure SetMaterial(const Value: Currency); function GetOther: Currency; procedure SetOther(const Value: Currency); function GetReturns: Currency; procedure SetReturns(const Value: Currency); function GetWorkerLabor: Double; procedure SetWorkerLabor(const Value: Double); function GetMachinistLabor: Double; procedure SetMachinistLabor(const Value: Double); function GetDebris: Double; procedure SetDebris(const Value: Double); procedure SetCapacity(const Value: Integer); function GetGrunt: Double; procedure SetGrunt(const Value: Double); public const iDirect=0; const iWorkerSalary=1; const iMachines=2; const iMachinistSalary=3; const iMaterial=4; const iOther=5; const iReturns=6; const iWorkerLabor=7; const iMachinistLabor=8; const iDebris=9; const iOMass=10; const iGrunt=11; const iWeightN=12; const iWeightB=13; const iStartupLoaded=16; public property Capacity: Integer read FCapacity write SetCapacity; property Direct: Currency read GetDirect write SetDirect; property WorkerSalary: Currency read GetWorkerSalary write SetWorkerSalary; property Machines: Currency read GetMachines write SetMachines; property MachinistSalary: Currency read GetMachinistSalary write SetMachinistSalary; property Material: Currency read GetMaterial write SetMaterial; property Other: Currency read GetOther write SetOther; property Returns: Currency read GetReturns write SetReturns; property WorkerLabor: Double read GetWorkerLabor write SetWorkerLabor; property MachinistLabor: Double read GetMachinistLabor write SetMachinistLabor; property Debris: Double read GetDebris write SetDebris; property Grunt: Double read GetGrunt write SetGrunt; property StartupLoaded: Double read GetStartupLoaded write SetStartupLoaded; constructor Create(const Txt: string); overload; procedure FromTxt(const Txt: string); procedure Clear; inline; function ToTxt: string; inline; function ToUtf8: RawUtf8; end; /// Запись для хранения Информации о защите Сметы (SYS_TABLE.PROTECTION_INFORMATION) TRDBProtectionInfo = record private FProtInfo: RawUtf8; FParamSeparator: AnsiChar; function GetParam(const Idx: Integer): string; function GetParamU(const Idx: Integer): RawUtf8; function GetText: string; function GetTextU: RawUtf8; procedure SetParam(const Idx: Integer; const Value: string); procedure SetParamU(const Idx: Integer; const Value: RawUtf8); procedure SetText(const AValue: string); procedure SetTextU(const AValue: RawUtf8); public property ParamSeparator: AnsiChar read FParamSeparator write FParamSeparator; property Param[const Idx: Integer]: string read GetParam write SetParam; property ParamU[const Idx: Integer]: RawUtf8 read GetParamU write SetParamU; property Text: string read GetText write SetText; property TextU: RawUtf8 read GetTextU write SetTextU; constructor Create(const AText: string; const ASep: AnsiChar='#'); procedure Clear; end; const BWVLinkISysRecID = 0; BWVLinkIFileName = 1; BWVLinkIItemNum = 2; BWVLinkIItemName = 3; BWVLinkIItemUnit = 4; BWVLinkIItemQty = 5; BWVLinkCount = 6; BWVLinkSep: AnsiChar = '#'; type /// Запись с информацией о связи с ведомостью объёмов TRDBBWVLink = record private FLinkItems: TRawUtf8DynArray; function GetSysRecID: RawUtf8; function GetFileName: RawUtf8; function GetItemNum: Integer; function GetItemName: RawUtf8; function GetItemUnit: RawUtf8; function GetItemQty: RawUtf8; function GetItemQtyD: Double; function GetLinkStr: string; function GetText: RawUtf8; procedure SetSysRecID(const AValue: RawUtf8); procedure SetFileName(const AValue: RawUtf8); procedure SetItemNum(const AValue: Integer); procedure SetItemName(const AValue: RawUtf8); procedure SetItemUnit(const AValue: RawUtf8); procedure SetItemQty(const AValue: RawUtf8); procedure SetItemQtyD(const AValue: Double); procedure SetLinkStr(const AValue: string); procedure SetText(const AValue: RawUtf8); public property SysRecID: RawUtf8 read GetSysRecID write SetSysRecID; property FileName: RawUtf8 read GetFileName write SetFileName; property ItemNum: Integer read GetItemNum write SetItemNum; property ItemName: RawUtf8 read GetItemName write SetItemName; property ItemUnit: RawUtf8 read GetItemUnit write SetItemUnit; property ItemQty: RawUtf8 read GetItemQty write SetItemQty; property ItemQtyD: Double read GetItemQtyD write SetItemQtyD; property LinkStr: string read GetLinkStr write SetLinkStr; property Text: RawUtf8 read GetText write SetText; constructor Create(const R: RawUtf8); procedure Init(const R: RawUtf8); end; const /// Набор типов защищаемых книг RDBProtectedBooks: TRDBBookTypes = [rdbBTPriceBook, rdbBTPriceList, rdbBTMachines]; var /// Массив наименований разделов документа (корневых узлов) RDBEstDocRootNames: TRawUTF8DynArray; type /// Тип сметно-нормативной базы TRDBBookBase = (rbbFER, rbbMNB, rbbPIR, rbbGSN, rbbMSC, rbbNone); /// Набор типов сметно-нормативных баз TRDBBookBases = set of TRDBBookBase; /// Информация об авторе сборников TRDBAuthorInfo = record private FName: RawByteString; FEdition: Integer; FCode: RawByteString; FRegion: string; procedure SetCode(const Value: RawByteString); procedure SetEdition(const Value: Integer); procedure SetName(const Value: RawByteString); procedure SetRegion(const Value: string); public /// Код идентифицирующий автора property Code: RawByteString read FCode write SetCode; /// Наименование автора property Name: RawByteString read FName write SetName; /// Регион для которого автор формирует СНБ property Region: string read FRegion write SetRegion; /// Редакция СНБ property Edition: Integer read FEdition write SetEdition; /// Процедура очищает запись procedure Clear; /// Функция инициализирует запись из JSON-документа function FromDoc(Doc: PDocVariantData): Boolean; /// Функция возвращает true, если федеральный автор function IsFederal: Boolean; inline; /// Функция выгружает запись в JSON-документ function ToDoc: Variant; end; /// Указатель на запись с информацией об авторе PRDBAuthorInfo = ^TRDBAuthorInfo; /// Массив записей с информацией об авторе TRDBAuthorInfos = array of TRDBAuthorInfo; /// Запись с информацией о сборнике (книге) TRDBBookInfo = record private FAuthorIdx: Integer; FAuthor: string; FReleaseDate: TDateTime; FFirstFactor: Integer; FID: string; FCaption: string; FConfirmDoc: string; FBase: TRDBBookBase; FEntryDate: TDateTime; FFRSNNum: Integer; FFRSNNums: string; FFRSNType: string; FFRSNName: string; FFRSNDate: string; procedure SetAuthor(const Value: string); procedure SetAuthorIdx(const Value: Integer); procedure SetBase(const Value: TRDBBookBase); procedure SetCaption(const Value: string); procedure SetConfirmDoc(const Value: string); procedure SetEntryDate(const Value: TDateTime); procedure SetFirstFactor(const Value: Integer); procedure SetID(const Value: string); procedure SetReleaseDate(const Value: TDateTime); procedure SetFRSNDate(const Value: TDateTime); procedure SetFRSNName(const Value: string); procedure SetFRSNNum(const Value: Integer); procedure SetFRSNType(const Value: string); function GetFRSNDate: TDateTime; procedure SetFRSNNums(const Value: string); public /// Идентификатор книги property ID: string read FID write SetID; /// Наименование книги property Caption: string read FCaption write SetCaption; /// Тип сметно-нормативной базы property Base: TRDBBookBase read FBase write SetBase; /// Код автора книги property Author: string read FAuthor write SetAuthor; /// Индекс в списке авторов property AuthorIdx: Integer read FAuthorIdx write SetAuthorIdx; /// Дата ввода книги в действие property EntryDate: TDateTime read FEntryDate write SetEntryDate; /// Утверждающий документ property ConfirmDoc: string read FConfirmDoc write SetConfirmDoc; /// Дата выпуска книги property ReleaseDate: TDateTime read FReleaseDate write SetReleaseDate; /// Первый индекс к книге property FirstFactor: Integer read FFirstFactor write SetFirstFactor; property FRSNType: string read FFRSNType write SetFRSNType; /// Номер документа в ФРСН property FRSNNum: Integer read FFRSNNum write SetFRSNNum; /// в случае если одной записи соответствует несколько номеров, то это список остальных номеров property FRSNNums: string read FFRSNNums write SetFRSNNums; property FRSNDate: TDateTime read GetFRSNDate write SetFRSNDate; property FRSNName: string read FFRSNName write SetFRSNName; /// Функция преобразует TRDBBookBase в строковое значение class function BookBaseToStr(const bb: TRDBBookBase): string; static; /// Функция преобразует строковое значение в TRDBBookBase class function BookBaseFromStr(const bb: string): TRDBBookBase; static; /// Функция преобразует строковое значение в TRDBBookBase class function BookBaseFromUtf8(const bb: RawUtf8): TRDBBookBase; static; /// Конструктор constructor Create(Doc: Variant); /// Процедура очищает запись с информацией о сборнике procedure Clear; /// Функция разыскивает номер в списке номеров FRSNNums function FindFRSNNum(const num: Integer): Boolean; /// Функция инициализирует запись из JSON-документа function FromDoc(Doc: PDocVariantData): Boolean; /// Функция выгружает запись в JSON-документ function ToDoc: Variant; end; /// Указатель на запись с информацией о сборнике PRDBBookInfo = ^TRDBBookInfo; /// Массив записей с информацией о сборнике TRDBBookInfos = array of TRDBBookInfo; /// типы элементов содержания RDB-документа TRDBDocItemType = (rditSection, rditCredit, rditPosition, rditUndefined); /// Элемент содержимого RDB-документа TRDBDocItem = record /// Тип элемента ItemType: TRDBDocItemType; /// Идентификатор элемента ItemID: string; /// Номер строки документа Line: Integer; /// Уровень иерархии Level: Integer; /// Глубина положения Deepness: Integer; /// Номер элемента Num: Integer; end; /// Обработчик события элемента содержимого RDB-документа TRDBDocItemEvent = procedure (Sender: TObject; const Item: TRDBDocItem) of object; TRDBMethodicTableItem = record ID: RawUtf8; Name: RawUtf8; Author: TRDBMethodicAuthor; mClass: RawUtf8; mGUID: TGUID; end; TRDBMethodicTableItemDynArray = array of TRDBMethodicTableItem; TRDBBookDynArray = array of IBook; TRDBEstBookDynArray = array of IEstBook; TRDBEstDocumentDynArray = array of IEstDocument; TRDBObjDocumentDynArray = array of IObjectEstimate; /// Обработчик события извлечения внедренной сметы TRDBOnEmbeddedBookEvent = procedure (Book: IBook; var Next: Boolean; const Flag: Int64; const ID: string) of object; var RDB2_ServerRootDirectory: TFileName; BaseMethodicNames: TEstimateBaseMethodicNames; BaseMethodicNamesUTF8: TEstimateBaseMethodicNamesUTF8; function String1251ToUtf8(const P: PAnsiChar; const Len: Integer): RawUtf8; function String1251ToWideString(const P: PAnsiChar; const Len: Integer): WideString; /// Функция возвращает идентификатор книги по её параметрам function GetBookOpenID(const BaseID, AuthorID, TypeName, Region, ShortName: AnsiString): AnsiString; overload; /// Функция возвращает идентификатор книги по её заголовку function GetBookOpenID(const H: TDocHeader): RawByteString; overload; /// Функция загружает из потока заголовок файла-документа function GetDocHeader(Stream: TStream; Code: boolean; FromBegin:boolean=true): TDocHeader; overload; /// Функция загружает из файла заголовок файла-документа function GetDocHeader(FileName: TFilename; Code: boolean; FromBegin:boolean=true): TDocHeader; overload; /// Функция возвращает код типа заголовка function GetHeaderCodeType(H: PDocHeader): Integer; /// Функция конверироует формат TSF в Формат TSJ function ConvertF2J(Src: Variant; out Dst: Variant): Boolean; /// Функция конверироует формат TSJ в Формат TSF function ConvertJ2F(Src: Variant; out Dst: Variant): Boolean; /// Функция проверяет является ли JSON-документ сметой function CheckJsonDoc(const Doc: PDocVariantData): Boolean; /// Функция возвращает наименование вида книги function ClassNameFromBookClass(const C: TRDBBookClass): string; /// Функция возвращает вид книги по наименованию вида книги function ClassNameToBookClass(const S: string): TRDBBookClass; /// Функция возвращает тип книги по наименованию типа function BookTypeNameFromString(const S: string): TRDBBookType; /// Функция возвращает наименованию типа книги function BookTypeNameToString(const bt: TRDBBookType): string; function DecodeHeaderBuf(var Buf): boolean; implementation function BookTypeNameFromString(const S: string): TRDBBookType; begin if S='PRICE_BOOK' then Result:=rdbBTPriceBook else if S='PRICE_LIST' then Result:=rdbBTPriceList else if S='MECH_BOOK' then Result:=rdbBTMachines else if S='ESN_BOOK' then Result:=rdbBTESNBook else if S='TRUD_BOOK' then Result:=rdbBTLabour else if S='TRANS_BOOK' then Result:=rdbBTTransport else if S=ServiceBookTypeName then Result:=rdbBTService else if S=ManDocTypeName then Result:=rdbBTMarketAnalisys else if S=VolDocTypeName then Result:=rdbBTVolumesList else if S=EstDocTypeName then Result:=rdbBTEstDocument else if S=ObjDocTypeName then Result:=rdbBTObjEstimate else if S=ConDocTypeName then Result:=rdbBTSumEstimate else Result:=rdbBTUndefined; end; function BookTypeNameToString(const bt: TRDBBookType): string; begin case bt of rdbBTEstDocument: Result:=EstDocTypeName; rdbBTObjEstimate: Result:=ObjDocTypeName; rdbBTSumEstimate: Result:=ConDocTypeName; rdbBTMarketAnalisys: Result:=ManDocTypeName; rdbBTVolumesList: Result:=VolDocTypeName; rdbBTService: Result:=ServiceBookTypeName; rdbBTResources: Result:=''; rdbBTPriceBook: Result:='PRICE_BOOK'; rdbBTPriceList: Result:='PRICE_LIST'; rdbBTMachines: Result:='MECH_BOOK'; rdbBTLabour: Result:='TRUD_BOOK'; rdbBTESNBook: Result:='ESN_BOOK'; rdbBTTransport: Result:='TRANS_BOOK'; else Result:=''; end; end; function CheckJsonDoc(const Doc: PDocVariantData): Boolean; var r:RawUTF8; begin Result:= (Doc<>nil) and (Doc^.Count>=RDBEswDocRootItemsCount); for r in RDBEstDocRootNames do if FindRawUTF8(Doc^.Names, r)<0 then begin Result:=False; Break; end; end; function ClassNameFromBookClass(const C: TRDBBookClass): string; begin case C of rdbBCStdEstBook: Result:='StdEstBook'; rdbBCEstDocument: Result:='EstDocument'; rdbBCObjDocument: Result:='ObjectEstimate'; rdbBCSumDocument: Result:='ConsolEstimate'; rdbBCMarketAnalisys: Result:='StdEstBook'; rdbBCVolumesList: Result:='StdEstBook'; else Result:=''; end; end; function ClassNameToBookClass(const S: string): TRDBBookClass; begin if S=EstStdBookTypeName then Result:=rdbBCStdEstBook else if S=EstDocTypeName then Result:=rdbBCEstDocument else if S=ObjDocTypeName then Result:=rdbBCObjDocument else if S=ConDocTypeName then Result:=rdbBCSumDocument else Result:=rbdBCUnknown; end; function ConvertF2J(Src: Variant; out Dst: Variant): Boolean; begin end; function ConvertJ2F(Src: Variant; out Dst: Variant): Boolean; var p: PDocVariantData; begin end; function GetHeaderCodeType(H: PDocHeader): Integer; var T: int64; begin MoveByOne(H,@T,SizeOf(T)); if T=0 then Result:=0 else if T=-1 then Result:=1 else Result:=2; end; function DecodeHeaderBuf(var Buf): boolean; begin case GetHeaderCodeType(@Buf) of 0: Result:=false; 1: begin DecodeBuffer(@Buf,dhSize); Result:=PDocHeader(@Buf).ClassName<>'StdEstBook'; end; 2: begin KeyDecodeBuffer(@Buf,THeaderBuf(Buf)[256],(dhSize div 4)+1); Result:=true; end; else Result:=False; end; end; function String1251ToUtf8(const P: PAnsiChar; const Len: Integer): RawUtf8; var cnv: TSynAnsiConvert; ptr: PUtf8Char; begin FastSetString(Result,nil,Len*3); ptr:=@Result[1]; cnv:=TSynAnsiConvert.Engine(1251); cnv.AnsiBufferToUtf8(ptr,P,Len); end; function String1251ToWideString(const P: PAnsiChar; const Len: Integer): WideString; var cnv: TSynAnsiConvert; ptr: PUtf8Char; r: RawUtf8; begin FastSetString(r,nil,Len*3); // ptr:=@r[1]; cnv:=TSynAnsiConvert.Engine(1251); // cnv.AnsiBufferToUtf8(ptr,P,Len); // Result:=cnv.AnsiToUnicodeString(p,len); Result:=cnv.AnsiToUnicodeString(r); end; function GetBookOpenID(const BaseID, AuthorID, TypeName, Region, ShortName: AnsiString): AnsiString; var R: String[23]; S: AnsiString; i, x: Integer; ts: {$IFDEF FPC} TString1251; {$ELSE} AnsiString; {$ENDIF} begin Result := ''; if (Pos('@', AuthorID) = 1) or (Pos('$', AuthorID) = 1) then Exit; if (TypeName <> 'PRICE_BOOK') and (TypeName <> 'PRICE_LIST') and (TypeName <> 'MECH_BOOK') then Exit; // ts := 'Новая20redaction09'; ts:=rusNewEdit; S := BaseID + AuthorID + ts + Region + ShortName; ts := BaseID + AuthorID + ts + Region + ShortName; if ts<>s then Exit; FillChar(R, 24, #0); Byte(R[0]) := 23; for i := 1 to Length(S) do begin x := ((i-1) mod 23)+1; Byte(R[x]) := (Byte(R[x])+Byte(S[i])) mod 256; if Byte(R[x]) = 0 then Byte(R[x]) := 255; end; Result := R; end; function GetBookOpenID(const H: TDocHeader): RawByteString; var R: String[23]; S: RawByteString; i, x: Integer; begin // Result := GetBookOpenID(H.Author, H.AuthorName, H.TypeName, H.Region, H.ShortName); Result := ''; if (Pos('@', H.AuthorName) = 1) or (Pos('$', H.AuthorName) = 1) then Exit; if (H.TypeName <> 'PRICE_BOOK') and (H.TypeName <> 'PRICE_LIST') and (H.TypeName <> 'MECH_BOOK') then Exit; // S := H.Author + H.AuthorName + 'Новая20redaction09' + H.Region + H.ShortName; S := H.Author + H.AuthorName + rusNewEdit + H.Region + H.ShortName; FillChar(R, 24, #0); Byte(R[0]) := 23; for i := 1 to Length(S) do begin x := ((i-1) mod 23)+1; Byte(R[x]) := (Byte(R[x])+Byte(S[i])) mod 256; if Byte(R[x]) = 0 then Byte(R[x]) := 255; end; Result := R; end; function GetDocHeader(Stream: TStream; Code: Boolean; FromBegin:boolean=true): TDocHeader; var Buf: THeaderBuf; P: integer; begin if FromBegin then P:=0 else P:=Stream.Position; FillChar(Result,dhSize,0); Stream.Position:=P; Stream.Read(Buf,1024); if Code then begin if DecodeHeaderBuf(Buf) then MoveByOne(@Buf, @Result, dhSize); end else MoveByOne(@Buf,@Result,dhSize); if Result.MacroPassword[0]=#255 then Result.MacroPassword:=''; end; function GetDocHeader(FileName: TFilename; Code: boolean; FromBegin:boolean=true): TDocHeader; overload; var stream: TFileStream; begin FillChar(Result,dhSize,0); if (FileName<>'') and (FileExists(FileName)) then begin stream:=TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone); try Result:=GetDocHeader(stream, Code); finally stream.Free; end; end; end; { TDocHeader } constructor TDocHeader.CreateEstDocument(const Methodic: string); begin ID:=''; ProjName:='EST'; ServerName:='RDB2'; ClassName:='EstDocument'; CompressionMethod:=1; CompressionLevel:=2; DriverLogVer:=5; DocFlags:=0; TypeName:='EST_DOCUMENT'; ShortName:=''; Name:=''; // FormatVer:=100860163 Region:=''; Author:=Methodic; AuthorName:=''; DataLevel:=0; Coauthors:=Methodic; ServiceFlag:=0; MacroFlag:=0; // KeyMask: array[0..7] of cardinal; //0..255 битовые флаги, соответсвтуют номерам 1..256 // NetMask: array[0..7] of word; //8 пар байтов описывают 8 сетевых ключей: 1-й байт - номер, 2-й байт - мощность //unsigned 16-bit // Password: string[23]; DriverID:=''; SourceID:=''; Edition:=0; Version:=0; RegionID:=''; end; function TDocHeader.GetAuthor: RawByteString; {$IFDEF FPC} var s: TString1251; {$ENDIF} begin {$IFDEF FPC} // s:=Author; Result:=s; Result:=Author; {$ELSE} Result:=Author; {$ENDIF} end; function TDocHeader.GetAuthorName: RawByteString; {$IFDEF FPC} var s: TString1251; {$ENDIF} begin {$IFDEF FPC} // s:=AuthorName; Result:=s; Result:=AuthorName; {$ELSE} Result:=AuthorName; {$ENDIF} end; function TDocHeader.GetBaseMethodic: TEstimateBaseMethodic; var i:TEstimateBaseMethodic; begin Result :=ebmDummy; for i := Low(TEstimateBaseMethodic) to High(TEstimateBaseMethodic) do if Author=BaseMethodicNames[i] then begin Result := i; Break; end; end; function TDocHeader.GetBookClass: TRDBBookClass; begin Result:=ClassNameToBookClass(ClassName); end; function TDocHeader.GetBookType: TRDBBookType; begin Result:=BookTypeNameFromString(TypeName); end; function TDocHeader.GetPassword: string; {$IFDEF FPC} var s: TString1251; {$ENDIF} begin {$IFDEF FPC} s:=Password; Result:=s; {$ELSE} Result:=Password; {$ENDIF} end; function TDocHeader.GetRegion: RawByteString; {$IFDEF FPC} var s: TString1251; {$ENDIF} begin {$IFDEF FPC} // s:=Region; Result:=s; Result:=Region; {$ELSE} Result:=Region; {$ENDIF} end; function TDocHeader.GetShortName: RawByteString; begin Result:=ShortName; end; procedure TDocHeader.SetBookClass(const Value: TRDBBookClass); begin ClassName:=ClassNameFromBookClass(Value); end; procedure TDocHeader.SetBookType(const Value: TRDBBookType); begin TypeName:=BookTypeNameToString(Value); end; function TDocHeader.ToDoc: Variant; begin TDocVariant.New(Result); TDocVariantData(Result).AddValue('ID',StringToUTF8(ID)); TDocVariantData(Result).AddValue('ProjName',StringToUTF8(ProjName)); TDocVariantData(Result).AddValue('ServerName',StringToUTF8(ServerName)); TDocVariantData(Result).AddValue('ClassName',StringToUTF8(ClassName)); TDocVariantData(Result).AddValue('CompressionMethod',CompressionMethod); TDocVariantData(Result).AddValue('CompressionLevel',CompressionLevel); TDocVariantData(Result).AddValue('BlobPos',BlobPos); TDocVariantData(Result).AddValue('UncompressedSize',UncompressedSize); TDocVariantData(Result).AddValue('TotalSize',TotalSize); TDocVariantData(Result).AddValue('DriverLogVer',DriverLogVer); TDocVariantData(Result).AddValue('DocFlags',DocFlags); TDocVariantData(Result).AddValue('TypeName',StringToUTF8(TypeName)); TDocVariantData(Result).AddValue('ShortName', String1251ToUTF8(@ShortName[1], Length(ShortName))); TDocVariantData(Result).AddValue('Name', String1251ToUTF8(@Name[1], Length(Name))); TDocVariantData(Result).AddValue('FormatVer',FormatVer); TDocVariantData(Result).AddValue('Region',String1251ToUTF8(@Region[1], Length(Region))); TDocVariantData(Result).AddValue('Author',StringToUTF8(Author)); TDocVariantData(Result).AddValue('AuthorName',String1251ToUTF8(@AuthorName[1], Length(AuthorName))); TDocVariantData(Result).AddValue('DataLevel',DataLevel); TDocVariantData(Result).AddValue('Coauthors',StringToUTF8(Coauthors)); TDocVariantData(Result).AddValue('DataMask',StringToUTF8(DataMask)); TDocVariantData(Result).AddValue('SerialNumber',SerialNumber); TDocVariantData(Result).AddValue('ServiceFlag',ServiceFlag); TDocVariantData(Result).AddValue('MacroFlag:',MacroFlag); TDocVariantData(Result).AddValue('MacroPassword',StringToUTF8(MacroPassword)); TDocVariantData(Result).AddValue('KeyMask',''); TDocVariantData(Result).AddValue('NetMask',''); TDocVariantData(Result).AddValue('Password',StringToUTF8(Password)); TDocVariantData(Result).AddValue('DriverID',StringToUTF8(DriverID)); TDocVariantData(Result).AddValue('SourceID',StringToUTF8(SourceID)); TDocVariantData(Result).AddValue('Edition',Edition); TDocVariantData(Result).AddValue('Version',Version); TDocVariantData(Result).AddValue('RegionID',StringToUTF8(RegionID)); { KeyMask: array[0..7] of cardinal; //0..255 битовые флаги, соответсвтуют номерам 1..256 NetMask: array[0..7] of word; //8 пар байтов описывают 8 сетевых ключей: 1-й байт - номер, 2-й байт - мощность //unsigned 16-bit } end; { TRDBFieldInfo } procedure TRDBFieldInfo.Clear; begin SetLength(Names,0); SetLength(Values,0); SetLength(Formulas,0); SetLength(Precisions,0); SetLength(FieldTypes,0); end; function TRDBFieldInfo.GetField(Index: integer): Variant; var r: string; begin if (Index<0) or (Index>=Length(FieldTypes)) then Result:=Null else if FieldTypes[Index] in [clt_String] then Result:=Values[Index] else begin r := Formulas[Index]; if (r='') or (r[1]<>'=') and (not DBDisNumber(r)) then Result:=StringToVariant(Values[Index], FieldType[Index]) else begin Result:=_Obj([]); TDocVariantData(Result).AddValue(RDBFieldValueName, StringToVariant(Values[Index], FieldType[Index])); TDocVariantData(Result).AddValue(RDBFieldFormulaName, r); TDocVariantData(Result).AddValue(RDBFieldPrecisionName, Precisions[Index]); end; end; end; function TRDBFieldInfo.GetFieldType(Index: integer): Integer; begin if (Index>=0) and (Index<Length(FieldTypes)) then Result:=FieldTypes[Index] else Result:=-1; end; function TRDBFieldInfo.GetFormula(Index: integer): string; begin if (Index>=0) and (Index<Length(Formulas)) then Result:=UTF8ToString(Formulas[Index]); end; function TRDBFieldInfo.GetIsResource(Index: integer): Boolean; begin Result:=IsResourceField(StringToUtf8(GetName(Index))); end; function TRDBFieldInfo.FieldIndexByNameS(const FieldName: string): Integer; begin Result:=FieldIndexByNameU(StringToUtf8(FieldName)); end; function TRDBFieldInfo.FieldIndexByNameU(const FieldName: RawUtf8): Integer; var i: Integer; begin Result:=-1; if FieldName='' then Exit; for i := Low(Names) to High(Names) do if Names[i]=FieldName then begin Result:=i; Break; end; end; function TRDBFieldInfo.GetCount: Word; begin Result:=Length(Names); end; function TRDBFieldInfo.GetName(Index: integer): string; begin Result := Utf8ToString(GetNameUtf8(Index)); end; function TRDBFieldInfo.GetNameUtf8(Index: integer): RawUtf8; begin if (Index>=0) and (Index<Length(Names)) then Result:=Names[Index] else Result:=''; end; function TRDBFieldInfo.GetPrecision(Index: integer): Integer; begin if (Index>=0) and (Index<Length(Precisions)) then Result:=Precision[Index] else Result:=-1; end; function TRDBFieldInfo.GetValue(Index: integer): string; begin if (Index>=0) and (Index<Length(Values)) then Result:=UTF8ToString(Values[Index]) else Result:=''; end; function TRDBFieldInfo.isEmpty: Boolean; begin Result:=Length(Names)=0; end; class function TRDBFieldInfo.IsResourceField(const FieldName: RawUTF8): Boolean; begin Result := (FieldName<>'') and ((FieldName=RDBResNameMachines) or (FieldName=RDBUnResNameMachines) or (FieldName=RDBResNameMaterial) or (FieldName=RDBUnResNameMaterial) or (FieldName=RDBResNameLabour) or (FieldName=RDBUnResNameLabour) ); end; function TRDBFieldInfo.isValid: Boolean; begin Result := (Length(Names)=Length(Formulas)) and (Length(Names)=Length(Values)) and (Length(Names)=Length(Precisions)) and (Length(Names)=Length(FieldTypes)); end; procedure TRDBFieldInfo.SetFieldType(Index: integer; const Value: Integer); begin if (Index>=0) and (Index<Length(FieldTypes)) then FieldTypes[Index]:=Value; end; procedure TRDBFieldInfo.SetFormula(Index: integer; const Value: string); begin if (Index>=0) and (Index<Length(Formulas)) then Formulas[Index]:=StringToUTF8(Value); end; procedure TRDBFieldInfo.SetCount(const Value: Word); begin SetLength(Names, Value); SetLength(Values, Value); SetLength(Formulas, Value); SetLength(Precisions, Value); SetLength(FieldTypes, Value); end; procedure TRDBFieldInfo.SetName(Index: integer; const Value: string); begin if (Index>=0) and (Index<Length(Names)) then Names[Index]:=StringToUTF8(Value); end; procedure TRDBFieldInfo.SetNameUtf8(Index: integer; const Value: RawUtf8); begin if (Index>=0) and (Index<Length(Names)) then Names[Index]:=Value; end; procedure TRDBFieldInfo.SetPrecision(Index: integer; const Value: Integer); begin if (Index>=0) and (Index<Length(Precisions)) then Precisions[Index]:=Value; end; procedure TRDBFieldInfo.SetValue(Index: integer; const Value: string); begin if (Index>=0) and (Index<Length(Formulas)) then Values[Index]:=StringToUTF8(Value); end; class function TRDBFieldInfo.StringToVariant(const aValue: RawUTF8; const afldTyp: Integer): Variant; var err: Integer; e: TSynExtended; begin if afldTyp in [clt_Calc] then begin e:=GetExtended(@aValue[1], err); if err=0 then Result:=e else Result:=aValue; end else Result:=aValue; end; class function TRDBFieldInfo.StrToUTF8(Src: TStringDynArray; Dst: TRawUTF8DynArray): Boolean; var i: Integer; begin Assert((Src<>nil) and (Dst<>nil), 'Массивы должны быть указаны'); Result:=(Length(Src)<=Length(Dst)); if Result then for i:=0 to Length(Src)-1 do Dst[i]:=StringToUTF8(Src[i]); end; function TRDBFieldInfo.ToDoc: Variant; var i: Integer; v: Variant; begin Result:=_Arr([]); v:=_Obj([]); for i := Low(Names) to High(Names) do begin TDocVariantData(v).AddValue('nm',Names[i]); TDocVariantData(v).AddValue('vl',Values[i]); TDocVariantData(v).AddValue('fr',Formulas[i]); TDocVariantData(v).AddValue('pr',Precisions[i]); TDocVariantData(v).AddValue('ft',FieldTypes[i]); TDocVariantData(Result).Additem(v); TDocVariantData(v).Clear; end; end; { TRDBResourceItem } procedure TRDBResourceItem.Clear; begin Cypher:=''; Name:=''; Ed:=''; NormPrice:=0.0; FactVol:=0.0; FactPrice:=0.0; Consumption:=0.0; UnAccounted:=False; end; constructor TRDBResourceItem.Create(const rt: TRDBBookType; const S: RawUtf8); begin ResType:=rt; FromRawUTF8(S); end; procedure TRDBResourceItem.FromJSON(const P: PDocVariantData); var r: RawUtf8; d: Double; begin {$IFDEF DEBUG} Assert((P<>nil) and (P^.Kind=dvObject),'P должен быть объектом'); {$ENDIF} if P^.GetAsRawUtf8('CYP', r) then Cypher:=r; if P^.GetAsRawUtf8('NAME', r) then Name:=r; if P^.GetAsRawUtf8('ED', r) then Ed:=r; if P^.GetAsDouble('PRICE', d) then NormPrice:=d; end; procedure TRDBResourceItem.FromRawUTF8(const R: rawUTF8); var ds: TRawUtf8DynArray; d: Double; sl,sr,p: RawUtf8; begin Clear; SetLength(ds,0); sl:=''; sr:=''; Data := R; UnAccounted:=False; // (Cypher#Name#Ed#NormPrice#FactVol#FactPrice=Value) DBDSplitTxtRight(R,'=',sl,sr); p:=StringToUtf8(rusP); if sr=p then begin Consumption:=0.0; UnAccounted:=True; end else if ToDouble(sr,d) then Consumption:=d else Consumption:=0.0; CSVToRawUTF8DynArray(@sl[1], ds, '#', True, True); Cypher:=ds[0]; if Length(ds)>1 then Name:=ds[1]; if Length(ds)>2 then Ed:=ds[2]; if (Length(ds)>3) and (ds[3]<>'') and ToDouble(ds[3],d) then NormPrice := d else NormPrice := 0.0; if (Length(ds)>4) and (ds[4]<>'') and ToDouble(ds[4],d) then FactVol := d else FactVol := 0.0; if (Length(ds)>5) and (ds[5]<>'') and ToDouble(ds[5],d) then FactPrice := d else FactPrice := 0.0; end; procedure TRDBResourceItem.FromString(const S: string); var sl,sr, sep: string; ds: TStringDynArray; function GetFloat(const s: string): Double; inline; begin if s='' then Result:=0.0 else if not DBDStringToDouble(s, Result) then Result:=0.0; end; begin Clear; Data := StringToUtf8(s); DBDSplitString(S,'=',sl,sr); UnAccounted:=(sr=RusP); Consumption:=GetFloat(sr); sep:='#'; DBDStringToArray(sl,'#',ds); Cypher := StringToUtf8(ds[0]); if Length(ds)>1 then Name := StringToUtf8(ds[1]); if Length(ds)>2 then Ed := StringToUtf8(ds[2]); if Length(ds)>3 then NormPrice := GetFloat(ds[3]); if Length(ds)>4 then FactVol := GetFloat(ds[4]); if Length(ds)>5 then FactPrice := GetFloat(ds[5]); end; function TRDBResourceItem.ToRawUTF8: RawUTF8; begin Result:=StringToUTF8(ToString); end; function TRDBResourceItem.ToString: string; begin // (Cypher#Name#Ed#NormPrice#FactVol#FactPrice=Value) Result:=Utf8ToString(Cypher)+'#'+Utf8ToSTring(Name)+'#'+Utf8ToSTring(Ed); if NormPrice<>0 then Result:=Result+'#'+CurrToStr(NormPrice) else if (FactVol<>0) or (FactPrice<>0) then Result:=Result+'#'; if FactVol<>0 then Result:=Result+'#'+FloatToStr(FactVol) else if FactPrice<>0 then Result:=Result+'#'; if FactPrice<>0 then Result:=Result+'#'+FloatToStr(FactPrice); if UnAccounted then Result:=Result+'='+RusP else Result:=Result+'='+FloatToStrF(Consumption, ffGeneral,18,8); if CodeOKP<>'' then Result:=Result+';'+Utf8ToString(CodeOKP); end; { RDBAuthorInfo } procedure TRDBAuthorInfo.Clear; begin FName:=''; FEdition:=0; FCode:=''; FRegion:=''; end; function TRDBAuthorInfo.FromDoc(Doc: PDocVariantData): Boolean; var rAut, rCap, rReg, rEd: RawUTF8; begin Clear; Result := Doc^.GetAsRawUTF8('AUTHOR', rAut) and Doc^.GetAsRawUTF8('CAPTION', rCap) and Doc^.GetAsRawUTF8('REGION', rReg) and Doc^.GetAsRawUTF8('EDITION', rEd) ; if Result then begin FName:=UTF8ToString(rCap); FCode:=UTF8ToString(rAut); FRegion:=UTF8ToString(rReg); if not ToInteger(rEd, FEdition) then FEdition:=0; end; end; function TRDBAuthorInfo.IsFederal: Boolean; begin Result:=(FRegion='Российская Федерация'); end; procedure TRDBAuthorInfo.SetCode(const Value: RawByteString); begin FCode := Value; end; procedure TRDBAuthorInfo.SetEdition(const Value: Integer); begin FEdition := Value; end; procedure TRDBAuthorInfo.SetName(const Value: RawByteString); begin FName := Value; end; procedure TRDBAuthorInfo.SetRegion(const Value: string); begin FRegion := Value; end; function TRDBAuthorInfo.ToDoc: Variant; begin Result:=_Obj([]); TDocVariantData(Result).AddValue('AUTHOR',StringToUTF8(FCode)); TDocVariantData(Result).AddValue('CAPTION',StringToUTF8(FName)); TDocVariantData(Result).AddValue('REGION',StringToUTF8(FRegion)); TDocVariantData(Result).AddValue('EDITION',FEdition); end; { TRDBBookInfo } class function TRDBBookInfo.BookBaseFromStr(const bb: string): TRDBBookBase; begin if bb='FER' then Result:=rbbFER else if bb='MNB' then Result:=rbbMNB else if bb='PIR' then Result:=rbbPIR else if bb='GNS' then Result:=rbbGSN else if bb='MSC' then Result:=rbbMSC else Result:=rbbNone; end; class function TRDBBookInfo.BookBaseFromUtf8(const bb: RawUtf8): TRDBBookBase; var s: string; begin s:=Utf8ToString(bb); if s='FER' then Result:=rbbFER else if s='MNB' then Result:=rbbMNB else if s='PIR' then Result:=rbbPIR else if s='GNS' then Result:=rbbGSN else if s='MSC' then Result:=rbbMSC else Result:=rbbNone; end; class function TRDBBookInfo.BookBaseToStr(const bb: TRDBBookBase): string; begin case bb of rbbFER: Result:='FER'; rbbMNB: Result:='MNB'; rbbPIR: Result:='PIR'; rbbGSN: Result:='GSN'; rbbMSC: Result:='MSC'; rbbNone: Result:=''; end; end; procedure TRDBBookInfo.Clear; begin FAuthorIdx:=-1; FAuthor:=''; FReleaseDate:=0; FFirstFactor:=0; FID:=''; FCaption:=''; FConfirmDoc:=''; FBase:=rbbNone; FEntryDate:=0; end; constructor TRDBBookInfo.Create(Doc: Variant); var p: PDocVariantData; begin p:=_Safe(Doc); FromDoc(p); end; function TRDBBookInfo.FindFRSNNum(const num: Integer): Boolean; var s: string; i: Integer; begin if FFRSNNum=num then Result:=True else begin i:=DBDFind(' '+FFRSNNums+',',' '+IntToStr(num)+',',1); Result:=i>0; end; end; function TRDBBookInfo.FromDoc(Doc: PDocVariantData): Boolean; var r,rID,rCap,rBas,rAut,rIdx,rAdd,rEDate,rConf, rRDate, rFirst: RawUTF8; i: Integer; begin i:=1; Clear; Result := Doc^.GetAsRawUTF8('ID',rID) and Doc^.GetAsRawUTF8('CAPTION',rCap) and Doc^.GetAsRawUTF8('BASEID',rBas) and Doc^.GetAsRawUTF8('AUTHOR',rAut) and Doc^.GetAsRawUTF8('CONFIRMDOC',rConf) and Doc^.GetAsRawUTF8('AINDEX',rIdx) and ToInteger(rIdx,FAuthorIdx) and Doc^.GetAsRawUTF8('ENTRYDATE',rEDate) and Doc^.GetAsRawUTF8('RELEASEDATE',rRDate) and Doc^.GetAsRawUTF8('FIRSTFACTORS',rFirst) ; if Result then begin FID:=UTF8ToString(rID); FCaption:=UTF8ToString(rCap); FBase:=BookBaseFromStr(UTF8ToString(rBas)); FAuthor:=UTF8ToString(rAut); FConfirmDoc:=UTF8ToString(rConf); try // if (rFirst='') or (rFirst='-') then FAuthorIdx:=0 // else ToInteger(rIdx,FAuthorIdx); if (rEDate='') or (rEDate='-') then FEntryDate:=0 else begin i:=1; DBDReadDate(UTF8ToString(rEDate), i, FEntryDate,dbdDOMandatoryDay, CurrentYear) end; if (rRDate='') or (rRDate='-') then FReleaseDate:=0 else begin i:=1; DBDReadDate(UTF8ToString(rRDate), i, FReleaseDate, dbdDOMandatoryDay, CurrentYear) end; if (rFirst='') or (rFirst='-') then FFirstFactor:=0 else FFirstFactor:=TDBDPriceDate.PriceDateFromStr(UTF8ToString(rFirst)); if Doc^.GetAsRawUtf8('FRSNTYPE', r) then SetFRSNType(Utf8ToString(r)) else SetFRSNType(''); if Doc^.GetAsRawUTF8('FRSNNUM', r) and (r<>'') then SetFRSNNums(Utf8ToString(r)) else SetFRSNNums('1'); if Doc^.GetAsRawUtf8('FRSNDATE',r) then FFRSNDate:=UTF8ToSTring(r) else FFRSNDate := ''; if Doc^.GetAsRawUtf8('FRSNNAME', r) then SetFRSNNAME(Utf8ToString(r)) else SetFRSNNAME(''); except Result:=False; end; end; end; function TRDBBookInfo.GetFRSNDate: TDateTime; var i: integer; begin i:=1; if (FFRSNDate='') or (not DBDReadDate(FFRSNDate, i, Result, dbdDOMandatoryDay, 2000)) then Result := FReleaseDate; end; procedure TRDBBookInfo.SetAuthor(const Value: string); begin FAuthor := Value; end; procedure TRDBBookInfo.SetAuthorIdx(const Value: Integer); begin FAuthorIdx := Value; end; procedure TRDBBookInfo.SetBase(const Value: TRDBBookBase); begin FBase := Value; end; procedure TRDBBookInfo.SetCaption(const Value: string); begin FCaption := Value; end; procedure TRDBBookInfo.SetConfirmDoc(const Value: string); begin FConfirmDoc := Value; end; procedure TRDBBookInfo.SetEntryDate(const Value: TDateTime); begin FEntryDate := Value; end; procedure TRDBBookInfo.SetFirstFactor(const Value: Integer); begin FFirstFactor := Value; end; procedure TRDBBookInfo.SetFRSNDate(const Value: TDateTime); begin DateTimeToString(FFRSNDate, 'dd.mm.yyyy', Value); end; procedure TRDBBookInfo.SetFRSNName(const Value: string); begin FFRSNName := Value; end; procedure TRDBBookInfo.SetFRSNNum(const Value: Integer); begin FFRSNNum := Value; end; procedure TRDBBookInfo.SetFRSNNums(const Value: string); var i,iPose: Integer; l,r: string; begin FFRSNNums := ''; if Value='' then Exit; if Value='1' then FFRSNNum:=1 else begin i := DBDStrUtils.DBDFindSubstr(Value,',',1); if i<1 then FFRSNNum:= StrToIntDef(Value,1) else begin l:=copy(Value, 1, i-1); FFRSNNum:= StrToIntDef(l,1); FFRSNNums:=DBDTrim(copy(Value, i+1, Length(Value)-i)); end; end; end; procedure TRDBBookInfo.SetFRSNType(const Value: string); begin FFRSNType := Value; end; procedure TRDBBookInfo.SetID(const Value: string); begin FID := Value; end; procedure TRDBBookInfo.SetReleaseDate(const Value: TDateTime); begin FReleaseDate := Value; end; function TRDBBookInfo.ToDoc: Variant; begin Result:=_Obj([]); TDocVariantData(Result).AddValue('ID', StringToUTF8(FID)); TDocVariantData(Result).AddValue('CAPTION', StringToUTF8(FCaption)); TDocVariantData(Result).AddValue('BASEID', StringToUTF8(BookBaseToStr(FBase))); TDocVariantData(Result).AddValue('AUTHOR', StringToUTF8(FAuthor)); TDocVariantData(Result).AddValue('AINDEX', Int32ToUtf8(FAuthorIdx)); TDocVariantData(Result).AddValue('ENTRYDATE', StringToUTF8(FormatDateTime('dd-mm-yyyy', FEntryDate))); TDocVariantData(Result).AddValue('CONFIRMDOC', StringToUTF8(FConfirmDoc)); TDocVariantData(Result).AddValue('RELEASEDATE', StringToUTF8(FormatDateTime('dd-mm-yyyy', FReleaseDate))); TDocVariantData(Result).AddValue('FIRSTFACTORS', StringToUTF8(TDBDPriceDate.PriceDateToStr(FFirstFactor))); TDocVariantData(Result).AddValue('FRSNTYPE', StringToUTF8(FFRSNType)); TDocVariantData(Result).AddValue('FRSNNUM', FFRSNNUM); TDocVariantData(Result).AddValue('FRSNDATE', StringToUTF8(FFRSNDate)); TDocVariantData(Result).AddValue('FRSNNAME', StringToUTF8(FFRSNName)); end; { TRDBTableRow } class function TRDBTableRow.GetFieldAsString(const pData: PDocVariantData; const Name: RawUtf8): string; begin Result:=Utf8ToString(GetFieldAsUtf8(pData, Name)); end; function TRDBTableRow.GetFieldAsString(Name: RawUtf8): string; begin Result:=GetFieldAsString(_Safe(Data), Name); end; class function TRDBTableRow.GetFieldAsUtf8(const pData: PDocVariantData; const Name: RawUtf8): RawUtf8; begin {$IFDEF DEBUG} Assert(Name<>'', 'Имя поля не может быть пустым'); Assert(PData<>nil, 'Указатель на JSON-документ не может быть nil'); {$ENDIF} if not pData^.GetAsRawUtf8('NAME',Result) then Result := ''; end; function TRDBTableRow.GetFieldAsUtf8(Name: RawUtf8): RawUtf8; begin Result:=GetFieldAsUtf8(_Safe(Data), Name); end; class function TRDBTableRow.GetFieldAsVariant(const pData: PDocVariantData; const Name: RawUtf8): Variant; begin {$IFDEF DEBUG} Assert(Name<>'', 'Имя поля не может быть пустым'); Assert(PData<>nil, 'Указатель на JSON-документ не может быть nil'); {$ENDIF} Result := pData^.GetValueOrNull('NAME'); end; function TRDBTableRow.GetFieldAsVariant(Name: RawUtf8): Variant; begin Result:=GetFieldAsVariant(_Safe(Data), Name); end; { TTsfValue } function TRDBCellValue.GetAsCurrency: Currency; var d: Double; begin d:=AsDouble; Result:=d; end; function TRDBCellValue.AsDouble: Double; var r: RawUTF8; begin r := AsUTF8; if r='' then Result:=0 else if not ToDouble(r,Result) then Result:=0; end; function TRDBCellValue.AsInteger: Integer; var r: RawUTF8; begin r := AsUTF8; if r='' then Result:=0 else if not ToInteger(r,Result) then Result:=0; end; function TRDBCellValue.AsString: string; begin Result:=UTF8ToString(AsUTF8); end; function TRDBCellValue.AsUTF8: RawUTF8; begin if (FData=nil) or (FData^.Kind=dvUndefined) then Result:=FValue else if not FData^.GetAsRawUTF8('Value',Result) then Result:=''; end; constructor TRDBCellValue.Create(P: PDocVariantData; const Name: RawUTF8); var v: Variant; i: Integer; begin FData:=nil; FValue:=''; if Name<>'' then begin i:=P^.GetValueIndex(Name); if i>=0 then begin v:=P^.Values[i]; FData:=_Safe(P^.Values[i]); if VarIsEmpty(v) or VarIsNull(v) then begin FValue:=''; end else begin if FData^.Kind=dvUndefined then FValue:= VariantToUTF8(P^.Values[i]); end; end; end; end; function TRDBCellValue.FromDocVariant(P: PDocVariantData; const Name: RawUTF8): Boolean; var v: Variant; i: Integer; begin FData:=nil; FValue:=''; if Name='' then Result:=False else begin i:=P^.GetValueIndex(Name); if i<0 then Result:=False else begin v:=P^.Values[i]; FData:=_Safe(P^.Values[i]); try if (FData^.Kind=dvUndefined) then FValue:= VariantToUTF8(v); Result:=True; except Result:=False; end; end; end; end; function TRDBCellValue.GetFormula: string; var r: RawUTF8; begin if FData^.GetAsRawUTF8('Formula',r) then Result:=UTF8ToString(r) else Result:=''; end; function TRDBCellValue.GetPrec: Integer; begin if not FData^.GetAsInteger('Precision', Result) then Result:=-1; end; function TRDBCellValue.GetValue: string; var r: RawUTF8; begin if FData^.GetAsRawUTF8('Value',r) then Result:=UTF8ToString(r) else Result:=''; end; function TRDBCellValue.isEmpty: Boolean; begin Result:=(GetValue='') and (GetFormula=''); end; function TRDBCellValue.isOne: Boolean; begin Result:=(AsCurrency=1) end; function TRDBCellValue.isString: Boolean; begin Result:=(FData=nil) end; function TRDBCellValue.isValid: Boolean; begin Result:=(FData^.Count>=3) and (FData^.Names[0]='Value'); end; function TRDBCellValue.isValidCoef: Boolean; begin Result := not (isZero or isOne); end; function TRDBCellValue.isZero: Boolean; begin Result:=(AsCurrency=0) end; procedure TRDBCellValue.SetAsCurrency(NewValue: Currency); begin FData^.AddOrUpdateValue('Value',CurrencyToStr(NewValue)); end; procedure TRDBCellValue.SetFormula(NewValue: string); begin FData^.AddOrUpdateValue('Value',StringToUTF8(NewValue)); end; procedure TRDBCellValue.SetPrec(NewValue: Integer); begin FData^.AddOrUpdateValue('Precision',NewValue); end; procedure TRDBCellValue.SetValue(NewValue: string); begin FData^.AddOrUpdateValue('Precision',StringToUTF8(NewValue)); end; { TRDBEmbeddedItem } procedure TRDBEmbeddedItem.SetDescription(const Value: RawUtf8); begin FDescription := Value; end; procedure TRDBEmbeddedItem.SetEmpty(const Value: Boolean); begin if Value then Clear; end; procedure TRDBEmbeddedItem.SetFilePath(const Value: RawUtf8); begin FFilePath := Value; end; procedure TRDBEmbeddedItem.SetFlag(const Value: Integer); begin FFlag:=Value; end; procedure TRDBEmbeddedItem.SetID(const Value: RawUtf8); begin FID:=Value; end; procedure TRDBEmbeddedItem.SetItemType(const Value: RawUtf8); begin FItemType := Value; end; procedure TRDBEmbeddedItem.SetModified(const Value: TDateTime); begin FModified := Value; end; procedure TRDBEmbeddedItem.SetName(const Value: RawUtf8); begin FName := Value; end; procedure TRDBEmbeddedItem.SetSize(const Value: Cardinal); begin FSize := Value; end; procedure TRDBEmbeddedItem.Clear; begin FSize:=0; FName:=''; FFilePath:=''; FModified:=0.0; FDescription:=''; FItemType:=''; FID:=''; FFlag:=0; end; function TRDBEmbeddedItem.GetEmpty: Boolean; begin Result:=(FName='') and (FSize=0); end; function TRDBEmbeddedItem.FromDoc(P: PDocVariantData): Boolean; var i: Int64; d: Double; begin Result := (P<>nil) and (P^.Kind=dvObject) and (P^.Count>2) and P^.GetAsRawUtf8('nm', FName) and P^.GetAsRawUtf8('it', FItemType) and P^.GetAsInt64('sz', i) and (i>=0) ; if Result then begin FSize:=i; FModified:=0.0; if not P^.GetAsRawUtf8('dsc', FDescription) then FDescription:=''; if not P^.GetAsRawUtf8('fp', FFilePath) then FFilePath:=''; if P^.GetAsDouble('mod',d) then FModified:=TDateTime(d); end; end; function TRDBEmbeddedItem.ToDoc: Variant; begin Result:=_Obj(['nm', FName, 'it', FItemType, 'sz', FSize]); if FDescription <> '' then TDocVariantData(Result).AddValue('dsc', FDescription); if FFilePath <> '' then TDocVariantData(Result).AddValue('fp', FFilePath); if FModified <>0.0 then TDocVariantData(Result).AddValue('mod', FModified); if FID <> '' then TDocVariantData(Result).AddValue('id', FID); if FFlag <> 0 then TDocVariantData(Result).AddValue('fl', FFlag); end; { TRDBNorms } procedure TRDBNorms.Clear; var i: Integer; begin for i := Low(arValues) to High(arValues) do arValues[i]:=0.0; end; constructor TRDBNorms.Create(const Txt: string); begin FCapacity:=iStartupLoaded+3; SetLength(arValues, FCapacity); FromTxt(Txt); end; function TRDBNorms.GetDebris: Double; begin Result:=_Get(iDebris); end; function TRDBNorms.GetDirect: Currency; begin Result:=_Get(iDirect); end; function TRDBNorms.GetGrunt: Double; begin Result:=_Get(iGrunt); end; function TRDBNorms.GetMachines: Currency; begin Result:=_Get(iMachines); end; function TRDBNorms.GetMachinistLabor: Double; begin Result:=_Get(iMachinistLabor); end; function TRDBNorms.GetMachinistSalary: Currency; begin Result:=_Get(iMachinistSalary); end; function TRDBNorms.GetMaterial: Currency; begin Result:=_Get(iMaterial); end; function TRDBNorms.GetOther: Currency; begin Result:=_Get(iOther); end; function TRDBNorms.GetReturns: Currency; begin Result:=_Get(iReturns); end; function TRDBNorms.GetStartupLoaded: Double; begin Result:=_Get(iStartupLoaded); end; function TRDBNorms.GetWorkerLabor: Double; begin Result:=_Get(iWorkerLabor); end; function TRDBNorms.GetWorkerSalary: Currency; begin Result:=_Get(iWorkerSalary); end; procedure TRDBNorms.SetCapacity(const Value: Integer); begin if Value<=0 then FCapacity:=0 else FCapacity := Value; SetLength(arValues, FCapacity); end; procedure TRDBNorms.SetDebris(const Value: Double); var r: RawUtf8; i: Integer; begin _Set(iDebris,Value); end; procedure TRDBNorms.SetDirect(const Value: Currency); var r: RawUtf8; i: Integer; begin _Set(iDirect,Value); end; procedure TRDBNorms.SetGrunt(const Value: Double); begin _Set(iGrunt,Value); end; procedure TRDBNorms.SetMachines(const Value: Currency); var r: RawUtf8; i: Integer; begin _Set(iMachines,Value); end; procedure TRDBNorms.SetMachinistLabor(const Value: Double); var r: RawUtf8; i: Integer; begin _Set(iMachinistLabor,Value); end; procedure TRDBNorms.SetMachinistSalary(const Value: Currency); var r: RawUtf8; i: Integer; begin _Set(iMachinistSalary,Value); end; procedure TRDBNorms.SetMaterial(const Value: Currency); var r: RawUtf8; i: Integer; begin _Set(iMaterial,Value); end; procedure TRDBNorms.SetOther(const Value: Currency); var r: RawUtf8; i: Integer; begin _Set(iOther,Value); end; procedure TRDBNorms.SetReturns(const Value: Currency); var r: RawUtf8; i: Integer; begin _Set(iReturns,Value); end; procedure TRDBNorms.SetStartupLoaded(const Value: Double); var r: RawUtf8; i: Integer; begin _Set(iStartupLoaded,Value); end; procedure TRDBNorms.SetWorkerLabor(const Value: Double); var r: RawUtf8; i: Integer; begin _Set(iWorkerLabor,Value); end; procedure TRDBNorms.SetWorkerSalary(const Value: Currency); var r: RawUtf8; i: Integer; begin _Set(iWorkerSalary,Value); end; procedure TRDBNorms.FromTxt(const Txt: string); var p: PUtf8Char; r: RawUtf8; arTxt: TRawUtf8DynArray; i: Integer; d: Double; begin Clear; if Length(arValues)<=FCapacity then SetLength(arValues, FCapacity); for i:=Low(arValues) to High(arValues) do arValues[i]:=0.0; if Txt='' then begin arValues[iStartupLoaded]:= -1.0; end else begin r:=StringToUtf8(Txt); p:=@r[1]; CsvToRawUtf8DynArray(p, arTxt,';',True,True); if Length(arTxt)>FCapacity then begin FCapacity:=Length(arTxt); SetLength(arValues, FCapacity); end; try for i := Low(arTxt) to High(arTxt) do if ToDouble(arTxt[i],d) then arValues[i]:= d; if (Length(artxt)<=iStartupLoaded) or (arTxt[iStartupLoaded]='') then arValues[iStartupLoaded]:= -1.0; except d:=0; end; end; end; function TRDBNorms.ToTxt: string; begin Result:=Utf8ToString(ToUtf8); end; function TRDBNorms.ToUtf8: RawUtf8; var i: Integer; begin Result:=''; for i := Low(arValues) to High(arValues) do begin if arValues[i]=0 then Result:=Result+';' else Result:=Result+DoubleToStr(arValues[i])+';'; end; Result:=DBDTrimAnsiChar(Result,';', dbdSPRight); end; function TRDBNorms._Get(const Idx: Integer): Double; begin Result:=arValues[Idx]; end; procedure TRDBNorms._Set(const Idx: Integer; const Value: Double); begin arValues[Idx]:=Value; end; { TRDBRebaseInfo } procedure TRDBRebaseInfo.Clear; begin SecTotalsOldBase:=0; SecTotalsNewBase:=0; SecTotalsLinesCount:=0; EstTotalsOldBase:=0; EstTotalsNewBase:=0; EstTotalsLinesCount:=0; end; procedure TRDBRebaseInfo.Init(const Base, Count: Integer; const Est: Boolean); begin if Est then begin EstTotalsOldBase:=Base; EstTotalsLinesCount:=Count; EstTotalsNewBase:=0; end else begin SecTotalsOldBase:=Base; SecTotalsLinesCount:=Count; SecTotalsNewBase:=0; end; end; function TRDBRebaseInfo.IsInit(const Est: Boolean): Boolean; begin if Est then begin Result:=(EstTotalsOldBase>0) and (EstTotalsLinesCount>0) end else begin Result:=(SecTotalsOldBase>0) and (SecTotalsLinesCount>0) end; end; function TRDBRebaseInfo.isReady(const Est: Boolean): Boolean; begin if Est then begin Result:=(EstTotalsOldBase>0) and (EstTotalsNewBase>0) and (EstTotalsLinesCount>0) end else begin Result:=(SecTotalsOldBase>0) and (SecTotalsNewBase>0) and (SecTotalsLinesCount>0) end; end; { TRDBBWVLink } constructor TRDBBWVLink.Create(const R: RawUtf8); begin SetText(R); end; function TRDBBWVLink.GetFileName: RawUtf8; begin if Length(FLinkItems)>BWVLinkIFileName then Result:=FLinkItems[BWVLinkIFileName] else Result:=''; end; function TRDBBWVLink.GetItemName: RawUtf8; begin if Length(FLinkItems)>BWVLinkIItemName then Result:=FLinkItems[BWVLinkIItemName] else Result:=''; end; function TRDBBWVLink.GetItemNum: Integer; var r: RawUtf8; begin if Length(FLinkItems)>BWVLinkIItemNum then begin r:=FLinkItems[BWVLinkIItemNum]; if not ToInteger(r, Result) then Result:=-2; end else Result:=-1; end; function TRDBBWVLink.GetItemQty: RawUtf8; begin if Length(FLinkItems)>BWVLinkIItemQty then Result:=FLinkItems[BWVLinkIItemQty] else Result:=''; end; function TRDBBWVLink.GetItemQtyD: Double; var r: RawUtf8; begin if Length(FLinkItems)>BWVLinkIFileName then begin r:=FLinkItems[BWVLinkIItemQty]; Result:=DBDUtf8ToDoubleDef(r,-2.0); end else Result:=-1.; end; function TRDBBWVLink.GetItemUnit: RawUtf8; begin if Length(FLinkItems)>BWVLinkIItemUnit then Result:=FLinkItems[BWVLinkIItemUnit] else Result:=''; end; function TRDBBWVLink.GetLinkStr: string; begin Result:=Utf8ToString(GetText); end; function TRDBBWVLink.GetSysRecID: RawUtf8; var p:PUtf8Char; begin if Length(FLinkItems)>BWVLinkISysRecID then Result:=FLinkItems[BWVLinkISysRecID] else Result:=''; Result:=StringToUtf8(ExtractFileName(Utf8ToString(Result))); end; function TRDBBWVLink.GetText: RawUtf8; begin Result:=RawUtf8ArrayToCsv(FLinkItems,BWVLinkSep); end; procedure TRDBBWVLink.Init(const R: RawUtf8); begin SetText(R); end; procedure TRDBBWVLink.SetFileName(const AValue: RawUtf8); begin if Length(FLinkItems)<BWVLinkCount then SetLength(FLinkItems,BWVLinkCount); FLinkItems[BWVLinkIFileName]:=AValue; end; procedure TRDBBWVLink.SetItemName(const AValue: RawUtf8); begin if Length(FLinkItems)<BWVLinkCount then SetLength(FLinkItems,BWVLinkCount); FLinkItems[BWVLinkIItemName]:=AValue; end; procedure TRDBBWVLink.SetItemNum(const AValue: Integer); begin if Length(FLinkItems)<BWVLinkCount then SetLength(FLinkItems,BWVLinkCount); FLinkItems[BWVLinkIItemNum]:=Int32ToUtf8(AValue); end; procedure TRDBBWVLink.SetItemQty(const AValue: RawUtf8); begin if Length(FLinkItems)<BWVLinkCount then SetLength(FLinkItems,BWVLinkCount); FLinkItems[BWVLinkIItemQty]:=AValue; end; procedure TRDBBWVLink.SetItemQtyD(const AValue: Double); begin if Length(FLinkItems)<BWVLinkCount then SetLength(FLinkItems,BWVLinkCount); FLinkItems[BWVLinkIItemQty]:=DoubleToStr(AValue); end; procedure TRDBBWVLink.SetItemUnit(const AValue: RawUtf8); begin if Length(FLinkItems)<BWVLinkCount then SetLength(FLinkItems,BWVLinkCount); FLinkItems[BWVLinkIItemUnit]:=AValue; end; procedure TRDBBWVLink.SetLinkStr(const AValue: string); begin SetText(StringToUtf8(AValue)); end; procedure TRDBBWVLink.SetSysRecID(const AValue: RawUtf8); begin if Length(FLinkItems)<BWVLinkCount then SetLength(FLinkItems,BWVLinkCount); FLinkItems[BWVLinkISysRecID]:=AValue; end; procedure TRDBBWVLink.SetText(const AValue: RawUtf8); var i: Integer; begin if AValue='' then begin if Length(FLinkItems)<BWVLinkCount then SetLength(FLinkItems,BWVLinkCount); for i := Low(FLinkItems) to High(FLinkItems) do FLinkItems[i]:=''; end else begin FLinkItems:=CsvToRawUtf8DynArray(AValue,BWVLinkSep); if Length(FLinkItems)<BWVLinkCount then SetLength(FLinkItems,BWVLinkCount); end; end; { TRDBProtectionInfo } procedure TRDBProtectionInfo.Clear; begin FProtInfo:=''; FParamSeparator:='#'; end; constructor TRDBProtectionInfo.Create(const AText: string; const ASep: AnsiChar); begin SetText(AText); FParamSeparator:=ASep; end; function TRDBProtectionInfo.GetParam(const Idx: Integer): string; begin Result:=Utf8ToString(GetParamU(Idx)); end; function TRDBProtectionInfo.GetParamU(const Idx: Integer): RawUtf8; var p: PUtf8Char; begin Result:=''; if (FProtInfo='') or (Idx<0) then Exit; p:=@FProtInfo[1]; Result:=GetCsvItem(p, Idx, FParamSeparator); end; function TRDBProtectionInfo.GetText: string; begin Result:=Utf8ToString(FProtInfo); end; function TRDBProtectionInfo.GetTextU: RawUtf8; begin Result:=FProtInfo; end; procedure TRDBProtectionInfo.SetParam(const Idx: Integer; const Value: string); begin Assert(false, 'Надо подождать реализации метода'); end; procedure TRDBProtectionInfo.SetParamU(const Idx: Integer; const Value: RawUtf8); begin Assert(False, 'Надо подождать реализации метода'); end; procedure TRDBProtectionInfo.SetText(const AValue: string); begin FProtInfo:=StringToUtf8(AValue); end; procedure TRDBProtectionInfo.SetTextU(const AValue: RawUtf8); begin FProtInfo:=AValue; end; initialization RDBFieldValueName:=StringToUTF8('Value'); RDBFieldFormulaName:=StringToUTF8('Formula'); RDBFieldPrecisionName:=StringToUTF8('Precision'); RDBItemSectionNameU:=StringToUTF8('Section'); RDBItemPositionNameU:=StringToUTF8('Position'); RDBItemCreditNameU:=StringToUTF8('Credit'); RDBFieldsSeparator:=cs_StdSeparator; SetLength(RDBEstDocRootNames, RDBEswDocRootItemsCount); RDBEstDocRootNames[0]:=StringToUTF8('HEADER'); RDBEstDocRootNames[1]:=StringToUTF8('SYS_TABLE'); RDBEstDocRootNames[2]:=StringToUTF8('USER_TABLE'); RDBEstDocRootNames[3]:=StringToUTF8('RESOURCE_TABLE'); RDBEstDocRootNames[4]:=StringToUTF8('ESN_TABLE'); RDBEstDocRootNames[5]:=StringToUTF8('METHODIC_TABLE'); RDBEstDocRootNames[6]:=StringToUTF8('VARIABLES'); RDBEstDocRootNames[7]:=StringToUTF8('ACT_TABLE'); RDBEstDocRootNames[8]:=StringToUTF8('PARAMETERS'); RDBEstDocRootNames[9]:=StringToUTF8('COMMANDS'); RDBEstDocRootNames[10]:=StringToUTF8('RESOURCES'); // RDBEstDocRootNames[11]:=StringToUTF8('CONSTRUCTIONS'); // RDBEstDocRootNames[12]:=StringToUTF8('VOLUMES'); RDBEstDocRootNames[13]:=StringToUTF8('GFACTORS'); RDBEstDocRootNames[14]:=StringToUTF8('REQUISITES'); RDBEstDocRootNames[15]:=StringToUTF8('MAIN_TABLE'); RDBEstDocTblHeaderName :='HEADER'; RDBEstDocTblHeaderNameU :=StringToUTF8(RDBEstDocTblHeaderName); RDBEstDocTblSysTable :='SYS_TABLE'; RDBEstDocTblSysTableU :=StringToUTF8(RDBEstDocTblSysTable); RDBEstDocTblUserTable :='USER_TABLE'; RDBEstDocTblUserTableU :=StringToUTF8(RDBEstDocTblUserTable); RDBEstDocTblResourceTable :='RESOURCE_TABLE'; RDBEstDocTblResourceTableU :=StringToUTF8(RDBEstDocTblResourceTable); RDBEstDocTblEsnTable :='ESN_TABLE'; RDBEstDocTblEsnTableU :=StringToUTF8(RDBEstDocTblEsnTable); RDBEstDocTblMethodicTable :='METHODIC_TABLE'; RDBEstDocTblMethodicTableU :=StringToUTF8(RDBEstDocTblMethodicTable); RDBEstDocTblVariables :='VARIABLES'; RDBEstDocTblVariablesU :=StringToUTF8(RDBEstDocTblVariables); RDBEstDocTblActTable :='ACT_TABLE'; RDBEstDocTblActTableU :=StringToUTF8(RDBEstDocTblActTable); RDBEstDocTblParameters :='PARAMETERS'; RDBEstDocTblParametersU :=StringToUTF8(RDBEstDocTblParameters); RDBEstDocTblCommands :='COMMANDS'; RDBEstDocTblCommandsU :=StringToUTF8(RDBEstDocTblCommands); RDBEstDocTblResources :='RESOURCES'; RDBEstDocTblResourcesU :=StringToUTF8(RDBEstDocTblResources); RDBEstDocTblConstructions :='CONSTRUCTIONS'; RDBEstDocTblConstructionsU :=StringToUTF8(RDBEstDocTblConstructions); RDBEstDocTblVolumes :='VOLUMES'; RDBEstDocTblVolumesU :=StringToUTF8(RDBEstDocTblVolumes); RDBEstDocTblGFactors :='GFACTORS'; RDBEstDocTblGFactorsU :=StringToUTF8(RDBEstDocTblGFactors); RDBEstDocTblRequisites :='REQUISITES'; RDBEstDocTblRequisitesU :=StringToUTF8(RDBEstDocTblRequisites); RDBEstDocTblMainTable :='MAIN_TABLE'; RDBEstDocTblMainTableU :=StringToUTF8(RDBEstDocTblMainTable); RDBResNameLabour := StringToUTF8('RESTRUD'); RDBUnResNameLabour :=StringToUTF8('NORESTRUD'); RDBResNameMaterial := StringToUTF8('RESMAT'); RDBUnResNameMaterial :=StringToUTF8('NORESSTR'); RDBResNameMachines := StringToUTF8('RESMEH'); RDBUnResNameMachines :=StringToUTF8('NORESSTRMECH'); RDBResEquipmnt := StringToUTF8('RESSTR'); RDB2_ServerRootDirectory:='C:\Строительный эксперт\'; TmpltJName := StringToUtf8('Tmplt'); BooksJName := StringToUtf8('Books'); OverdraftJName := StringToUtf8('Overdraft'); ProfitJName := StringToUtf8('Profitt'); ObjValIds[0]:=UTF8ToAnsi('Строй'); ObjValIds[1]:=UTF8ToAnsi('Монтаж'); ObjValIds[2]:=UTF8ToAnsi('Оборуд'); ObjValIds[3]:=UTF8ToAnsi('Проч'); ObjValIds[4]:=UTF8ToAnsi('Возврат'); ObjValIds[5]:=UTF8ToAnsi('ЗП'); ObjValFields[0]:='STROY'; ObjValFields[1]:='MONTAJ'; ObjValFields[2]:='OBORUD'; ObjValFields[3]:='PROCH'; ObjValFields[4]:='VOZVRAT'; ObjValFields[5]:='IZP'; ObjValCaptions[0]:='Стоимость строительных работ'; ObjValCaptions[1]:='Стоимость монтажных работ'; ObjValCaptions[2]:='Стоимость оборудования, мебели и инвентаря'; ObjValCaptions[3]:='Стоимость прочих затрат'; ObjValCaptions[4]:='Возвратные суммы'; ObjValCaptions[5]:='Средства на оплату труда'; ObjAllColsId:= 'Все графы'; BaseMethodicNames[ebmMP] := 'MP'; BaseMethodicNames[ebmMSC] := 'MSC'; BaseMethodicNames[ebmGSN] := 'GESN'; BaseMethodicNames[ebmFER] := 'FER'; BaseMethodicNames[ebmTSN] := 'MNB'; BaseMethodicNames[ebmPIR] := 'PIR'; BaseMethodicNames[ebmDummy] := ''; BaseMethodicNamesUTF8[ebmMP] := StringToUTF8(BaseMethodicNames[ebmMP]); BaseMethodicNamesUTF8[ebmMSC] := StringToUTF8(BaseMethodicNames[ebmMSC]); BaseMethodicNamesUTF8[ebmGSN] := StringToUTF8(BaseMethodicNames[ebmGSN]); BaseMethodicNamesUTF8[ebmFER] := StringToUTF8(BaseMethodicNames[ebmFER]); BaseMethodicNamesUTF8[ebmTSN] := StringToUTF8(BaseMethodicNames[ebmTSN]); BaseMethodicNamesUTF8[ebmPIR] := StringToUTF8(BaseMethodicNames[ebmPIR]); BaseMethodicNamesUTF8[ebmDummy] := ''; finalization end.