エルマを離れた方法

3年前、組織および管理文書の管理を自動化するために、エルマシステムが買収されました。 しかし、1年の運用後、放棄する必要があることが明らかになりました。



easla.comにエルマを残した経緯。



elmaを購入する前に、タスクの妥当性についてシステムの徹底的な分析が行われました。 私はシステムで以下が好きでした:



落とし穴がすぐに見えなかったのは残念です。 あまり詳細には触れませんが、運用開始から約3か月後、別の計画の問題が現れました。 もちろん、まず第一に、技術的な問題が心配でした。例えば:



他の問題がありました。 しかし、その後、エンドユーザーが気にしない技術的な問題。

ただし、ユーザーは次のような不便さについても定期的に不満を述べています。



1年稼働した後、 elmaはこのシステムが組織を停止させることに気づきました。 パフォーマンスを低下させることなく、他のプロセスを実装することはできません。 そして、プロセスを実装することにより、絶えず「クロールバグ」が発生した場合、プロセスが安定して動作するという保証はありません。 このシステムの利点はすべて無駄になりました。



検索する



elmaに代わるシステムが検索されました。 検索条件の1つは、無料または低コストでした。 組織の経営陣は新しいシステムの購入にお金を費やしたくありませんでした。私は、 エルマを購入し、その購入を正当化する決定を下したIT部門の責任者として、同じことに対して再びお金を要求することを恥じました。 また、基準のリストには次のものがありました。



easla.comがあらゆる点でアプローチしました。



開発



システムへの登録後、関連するビジネスプロセスの開発を開始しました。 さらに、オブジェクトの属性は、 elmaからインポートされたデータを受け入れることができるように実装する必要がありました

4つのプロセスが必要でした。



顧客プロセスはほとんどプロセスではありません。 オブジェクトにはステータスさえありません。 実際、これは互いに関連する取引相手と連絡先のディレクトリです。 しかし、取引相手は、属性の数が他のすべてのオブジェクトと異なります。 名前だけでなく、法定住所、住所、銀行の詳細も保存できます。 わずか40の属性! 連絡先は、取引相手の従業員である個人です。

当時の「契約」プロセスは、契約の単純なカタログでもありました。 文字の分類にのみ必要でした。

通信プロセスは、組織にとって非常に重要なプロセスです。 彼は公式の着信および発信の通信を管理します。これは技術的な決定の採用に影響を与え、法廷での紛争状況の解決に関与します。 入ってくる手紙は、早すぎるレビューや返信のために損失を引き起こす可能性があります。 発信レターは、タイムリーに送信されると、 6桁、時には7桁の利益をもたらします。 送信ドキュメントオブジェクトの重要な違いは次のとおりです。



タスクプロセスは、通信と同様に重要です。 論理的な継続です。 タスクの助けを借りて、 着信ドキュメントまたは発信ドキュメントごとに注文の実行が監視されます。 さらに、各タスクでは、人件費の登録が数分で行われ、一連の着信および発信レターが実行されます。

1か月でプロセスの開発を完了し、実際にデータをインポートするという疑問が生じました。 しかし、前-elmaからエクスポートします



輸出入



easla.comへのインポートには、考慮すべき機能がいくつかあります。



elmaからデータをアンロードする標準的な手段が見つからなかったため、データベースに登らなければなりませんでした。 elmaデータベースには多くの異なるテーブルがあり、必要なテーブルは直感的に見つかりました。 それでも、プログラマは同じように考えます。

単純なオブジェクトでエクスポートを開始しました。 取引先から。 このSQLクエリを作成しました。

ELMA_export_contragents.sql
SELECT DISTINCT [ELMA].[dbo].[Contractor].[Name] AS [crm_management_contragent_name] ,[LF].[LongName] AS [crm_management_contragent_opf] ,[ELMA].[dbo].[ContractorType].[Name] AS [crm_management_contragent_type] ,[Site] AS [crm_management_contragent_url] ,[crm_management_contragent_email] = STUFF(( SELECT '|' + [ELMA].[dbo].[Email].[EmailString] FROM [ELMA].[dbo].[Contractor_Email] LEFT OUTER JOIN [ELMA].[dbo].[Email] ON [ELMA].[dbo].[Email].[Id] = [ELMA].[dbo].[Contractor_Email].[Email] WHERE [ELMA].[dbo].[Contractor_Email].[Contractor] = [ELMA].[dbo].[Contractor].[Id] FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 1, '') ,[Fax] AS [crm_management_contragent_fax] ,[crm_management_contragent_phone] = STUFF(( SELECT '|' + [ELMA].[dbo].[Phone].[PhoneString] FROM [ELMA].[dbo].[Contractor_Phone] LEFT OUTER JOIN [ELMA].[dbo].[Phone] ON [ELMA].[dbo].[Phone].[Id] = [ELMA].[dbo].[Contractor_Phone].[Phone] WHERE [ELMA].[dbo].[Contractor_Phone].[Contractor] = [ELMA].[dbo].[Contractor].[Id] FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 1, '') ,[LAC].[Name] AS [crm_management_contragent_legal_country] ,[LA].[Region] AS [crm_management_contragent_legal_region] ,[LA].[District] AS [crm_management_contragent_legal_district] ,[LA].[City] AS [crm_management_contragent_legal_city] ,[LA].[Locality] AS [crm_management_contragent_legal_locality] ,[LA].[Street] AS [crm_management_contragent_legal_street] ,[LA].[Building] AS [crm_management_contragent_legal_house] ,[LA].[Stroenie] AS [crm_management_contragent_legal_building] ,[LA].[Korpus] AS [crm_management_contragent_legal_corp] ,[LA].[Appartment] AS [crm_management_contragent_legal_apartment] ,[LA].[Zip] AS [crm_management_contragent_legal_postcode] ,[PAC].[Name] AS [crm_management_contragent_post_country] ,[PA].[Region] AS [crm_management_contragent_post_region] ,[PA].[District] AS [crm_management_contragent_post_district] ,[PA].[City] AS [crm_management_contragent_post_city] ,[PA].[Locality] AS [crm_management_contragent_post_locality] ,[PA].[Street] AS [crm_management_contragent_post_street] ,[PA].[Building] AS [crm_management_contragent_post_house] ,[PA].[Stroenie] AS [crm_management_contragent_post_building] ,[PA].[Korpus] AS [crm_management_contragent_post_corp] ,[PA].[Appartment] AS [crm_management_contragent_post_apartment] ,[PA].[Zip] AS [crm_management_contragent_post_postcode] ,[INN] AS [crm_management_contragent_inn] ,[ELMA].[dbo].[ContractorLegal].[KPP] AS [crm_management_contragent_kpp] ,[ELMA].[dbo].[ContractorLegal].[OGRN] AS [crm_management_contragent_ogrn] ,[ELMA].[dbo].[ContractorLegal].[BIK] AS [crm_management_contragent_bik] ,[ELMA].[dbo].[ContractorLegal].[BANK] AS [crm_management_contragent_bank] ,[ELMA].[dbo].[ContractorLegal].[KS] AS [crm_management_contragent_ks] ,[ELMA].[dbo].[ContractorLegal].[RS] AS [crm_management_contragent_rs] FROM [ELMA].[dbo].[Contractor] LEFT OUTER JOIN [ELMA].[dbo].[ContractorType] ON [ELMA].[dbo].[ContractorType].[Id] = [ELMA].[dbo].[Contractor].[Type] LEFT OUTER JOIN [ELMA].[dbo].[ContractorLegal] ON [ELMA].[dbo].[ContractorLegal].[Id] = [ELMA].[dbo].[Contractor].[Id] LEFT OUTER JOIN [ELMA].[dbo].[Address] AS [LA] ON [LA].[Id] = [ELMA].[dbo].[Contractor].[LegalAddress] LEFT OUTER JOIN [ELMA].[dbo].[Country] AS [LAC] ON [LAC].[Id] = [LA].[Country] LEFT OUTER JOIN [ELMA].[dbo].[Address] AS [PA] ON [PA].[Id] = [ELMA].[dbo].[Contractor].[PostalAddress] LEFT OUTER JOIN [ELMA].[dbo].[Country] AS [PAC] ON [PAC].[Id] = [PA].[Country] LEFT OUTER JOIN [ELMA].[dbo].[LegalForm] AS [LF] ON [LF].[Id] = [ELMA].[dbo].[ContractorLegal].[LegalForm] WHERE [ELMA].[dbo].[Contractor].[IsDeleted] = 0 AND [ELMA].[dbo].[Contractor].[Name] IS NOT NULL AND [ELMA].[dbo].[Contractor].[id] > 500
      
      







STUFF(...)を使用して、1つの属性の複数の値を1つに結合しました。 クエリ結果は、区切り文字「;」を含むCSV形式で保存されました。 ファイルの最初の行は、 easla.comに属性表記を追加しました 。 Import Objectsセクションにファイルをアップロードしました。 次に、ファイルのエンコードとインポートするユーザーを指定しました。 インポートを開始しました。 インポート手順は非常に高速ではなく、各オブジェクトを作成するのに約1秒かかります。 インポートされたレコードの数は約500でした。次のようになりました。



今連絡します。 このSQLクエリを作成しました。

ELMA_export_contacts.sql
 SELECT [Surname] AS [crm_management_contact_lastname] ,[Firstname] AS [crm_management_contact_firstname] ,[Middlename] AS [crm_management_contact_middlename] ,[ELMA].[dbo].[Contractor].[Name] AS [crm_management_contact_contragent] ,[Department] AS [cnt_management_contact_department] ,[Position] AS [cnt_management_contact_position] ,[crm_management_contact_email] = STUFF(( SELECT '|' + [ELMA].[dbo].[Email].[EmailString] FROM [ELMA].[dbo].[Contact_Email] LEFT OUTER JOIN [ELMA].[dbo].[Email] ON [ELMA].[dbo].[Email].[Id] = [ELMA].[dbo].[Contact_Email].[Email] WHERE [ELMA].[dbo].[Contact_Email].[Contact] = [ELMA].[dbo].[Contact].[Id] FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 1, '') ,[crm_management_contact_phone] = STUFF(( SELECT '|' + [ELMA].[dbo].[Phone].[PhoneString] FROM [ELMA].[dbo].[Contact_Phone] LEFT OUTER JOIN [ELMA].[dbo].[Phone] ON [ELMA].[dbo].[Phone].[Id] = [ELMA].[dbo].[Contact_Phone].[Phone] WHERE [ELMA].[dbo].[Contact_Phone].[Contact] = [ELMA].[dbo].[Contact].[Id] FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 1, '') ,CASE WHEN [Year] IS NULL THEN NULL ELSE CONVERT(varchar, [Birthday],104) END AS [crm_management_contact_birthday] ,[RAC].[Name] AS [crm_management_contact_country] ,[RA].[Region] AS [crm_management_contact_region] ,[RA].[District] AS [crm_management_contact_district] ,[RA].[City] AS [crm_management_contact_city] ,[RA].[Locality] AS [crm_management_contact_locality] ,[RA].[Street] AS [crm_management_contact_street] ,[RA].[Building] AS [crm_management_contact_house] ,[RA].[Stroenie] AS [crm_management_contact_building] ,[RA].[Korpus] AS [crm_management_contact_corp] ,[RA].[Appartment] AS [crm_management_contact_apartment] ,[RA].[Zip] AS [crm_management_contact_postcode] FROM [ELMA].[dbo].[Contact] LEFT OUTER JOIN [ELMA].[dbo].[Contractor] ON [ELMA].[dbo].[Contractor].[Id] = [ELMA].[dbo].[Contact].[Contractor] LEFT OUTER JOIN [ELMA].[dbo].[Address] AS [RA] ON [RA].[Id] = [ELMA].[dbo].[Contact].[RegistrationAddress] LEFT OUTER JOIN [ELMA].[dbo].[Country] AS [RAC] ON [RAC].[Id] = [RA].[Country] WHERE [ELMA].[dbo].[Contact].[Id] > 1919
      
      







すべてのアクションは、以前のインポートに似ています。 取引先の後に取引先責任者をインポートする特性は、取引先を参照する属性「取引先」が取引先責任者にあることです。 したがって、まず最初に、請負業者がインポートされ、その後連絡を取りました。 連絡先を「 取引先 」フィールドにインポートする easla.com は取引先へのリンクを見つけて置換しました ! インポートされたレコードの数は約1800でした。

取引先と連絡先をインポートすると、すべての連絡先が特定の取引先に属する構造化されたデータベースができます。 データのインポートには約2時間かかりました。 さらに、彼はSQLクエリの開発に半分の時間を費やしました。 その結果、2つの既製の相互接続されたテーブルが得られました。

取引先レジストリ:



連絡先登録:



次のステップは、契約のインポートでした。 このSQLクエリを使用してアンロードします。

ELMA_export_contracts.sql
 SELECT [RegYear] AS [agr_management_contract_year] ,[RegNum] AS [agr_management_contract_num] ,[RegAppendixFront] AS [agr_management_contract_appendix_front] ,[RegAppendixBack] AS [agr_management_contract_appendix_back] ,[RegCode] ,[ELMA].[dbo].[Contractor].[Name] AS [agr_management_contract_contragent] ,'"'+REPLACE(REPLACE(REPLACE([Title],CHAR(10),''),CHAR(13),''),';',',')+'"' AS [agr_management_contract_title] ,CONVERT(varchar, [RegDate],104) AS [agr_management_contract_reg_date] ,CONVERT(varchar, [SignDate],104) AS [agr_management_contract_sign_date] ,[PM1].[EMail] AS [agr_management_contract_project_manager] ,[PM2].[EMail] AS [agr_management_contract_project_manager_helper] ,agr_management_contract_fields = STUFF(( SELECT '|' + [F1].[Title] FROM [ELMA].[dbo].[Project_Fields] LEFT OUTER JOIN [ELMA].[dbo].[Field] AS [F1] ON [F1].[Id] = [ELMA].[dbo].[Project_Fields].[Field] WHERE [ELMA].[dbo].[Project_Fields].[Parent] = [ELMA].[dbo].[Project].[Id] FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 1, '') FROM [ELMA].[dbo].[Project] LEFT JOIN [ELMA].[dbo].[Contractor] ON [ELMA].[dbo].[Contractor].[Id] = [ELMA].[dbo].[Project].[Contragent] LEFT JOIN [ELMA].[dbo].[User] AS [PM1] ON [PM1].[Id] = [ELMA].[dbo].[Project].[ProjectManager] LEFT JOIN [ELMA].[dbo].[User] AS [PM2] ON [PM2].[Id] = [ELMA].[dbo].[Project].[ProjectManagerHelper]
      
      







すべてのアクションも前のインポートに似ています。 また、連絡先と同様に、「取引相手」属性を持つすべての契約は、インポート時に関連する取引先に連絡しました。 インポートされたレコードの数は200を少し超えていました。



これで、受信ドキュメントと送信ドキュメントによって参照されるすべての請負業者、連絡先、契約がeasla.comにあったときに 、通信のインポートを開始することができました。

着信および発信の文字数は多く、それぞれ約5400および5300でした。

着信文字と発信文字が相互に参照すること、つまり 着信に応じて発信を送信でき、これに関する情報は発信ドキュメントの対応する属性に格納されます。 発信ドキュメントへの応答として着信ドキュメントを受信でき、これに関する情報は着信ドキュメントの対応する属性に格納されます。 したがって、いずれかのタイプのオブジェクトをインポートする場合、すべての関係の形成保証することは不可能です。 最初に着信ドキュメントをインポートしますが、それ以前は、発信ドキュメントへのリンクを保存する属性のタイプが「オブジェクト」から「文字列」に変更されました。 これにより、データベースにまだない属性に発信ドキュメントの説明を保存し、発信ドキュメントをインポートした後でそれを使用することができました。 最終的に、着信ドキュメントをアンロードするために、次のSQLクエリを取得しました。

ELMA_export_incomings.sql
 SELECT CASE [DocMethod] WHEN 1 THEN '. ' WHEN 2 THEN ' ' WHEN 3 THEN '' WHEN 4 THEN ' ' END AS [crs_management_incoming_method] ,[ELMA].[dbo].[Contractor].[Name] AS [crs_management_incoming_contragent] ,[ELMA].[dbo].[Contact].[Surname] + ' ' + SUBSTRING([ELMA].[dbo].[Contact].[Firstname],1,1) + '.' + SUBSTRING([ELMA].[dbo].[Contact].[Middlename],1,1) + '.' AS [crs_management_incoming_contact] ,[crs_management_incoming_performers] = STUFF(( SELECT '|' + [C1].[Surname] + ' ' + SUBSTRING([C1].[Firstname],1,1) + '.' + SUBSTRING([C1].[Middlename],1,1) + '.' FROM [ELMA].[dbo].[IncomingDoc_Performers] LEFT OUTER JOIN [ELMA].[dbo].[Contact] AS [C1] ON [C1].[Id] = [ELMA].[dbo].[IncomingDoc_Performers].[Performer] WHERE [ELMA].[dbo].[IncomingDoc_Performers].[Parent] = [ELMA].[dbo].[IncomingDoc].[Id] FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 1, '') ,CONVERT(varchar, [ELMA].[dbo].[IncomingDoc].[ContragentDate], 104) AS [crs_management_incoming_contragent_date] ,[ELMA].[dbo].[IncomingDoc].[ContragentRegNum] AS [crs_management_incoming_contragent_regnum] ,CONVERT(VARCHAR,[ELMA].[dbo].[IncomingDoc].[ReceiveDate],20) AS [crs_management_incoming_receive_date] ,[ELMA].[dbo].[IncomingDoc].[ReceiveOriginalDate] AS [crs_management_incoming_receive_original_date] ,[ReceiveOriginalDateFlag] AS [crs_management_incoming_receive_original_flag] ,[ELMA].[dbo].[IncomingDoc].[ReceiveRegNum] AS [crs_management_incoming_receive_regnum] ,REPLACE(REPLACE([ELMA].[dbo].[IncomingDoc].[Subj],CHAR(13),''),CHAR(10),'') AS [crs_management_incoming_subj] ,CASE [ELMA].[dbo].[IncomingDoc].[DocType] WHEN 0 THEN '' WHEN 1 THEN '' WHEN 2 THEN '  ' WHEN 3 THEN '  ' WHEN 4 THEN '  ' WHEN 5 THEN ' ' WHEN 6 THEN '   ' WHEN 7 THEN ' ' WHEN 8 THEN ' ' WHEN 9 THEN '' WHEN 13 THEN '' WHEN 14 THEN '' WHEN 17 THEN '' WHEN 15 THEN '' WHEN 10 THEN '' WHEN 18 THEN '   ' WHEN 11 THEN '  ' WHEN 12 THEN ' ' WHEN 16 THEN ' ' WHEN 99 THEN '' END AS [crs_management_incoming_content] ,[U1].[UserName]+'@sngp.ru' AS [crs_management_incoming_to] ,[U2].[UserName]+'@sngp.ru' AS [crs_management_incoming_forwardto] ,[ELMA].[dbo].[OutgoingDoc].[RegNum] AS [crs_management_incoming_outgoing] ,[ELMA].[dbo].[Project].[RegCode] AS [crs_management_incoming_contract] ,[crs_management_incoming_attachments] = STUFF(( SELECT '|' + REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(LTRIM(STR([F0].[Id]) + ' ' + [F0].[Name]),'«',''),'»',''),'–','-'),'.zip.zip','.zip'),'.docx','.docx'),' ',' ') FROM [ELMA].[dbo].[IncomingDoc_DocAttachments] LEFT OUTER JOIN [ELMA].[dbo].[FS_FILES] AS [F0] ON [F0].[Uid] = [ELMA].[dbo].[IncomingDoc_DocAttachments].[DocAttachment] WHERE [ELMA].[dbo].[IncomingDoc_DocAttachments].[Parent] = [ELMA].[dbo].[IncomingDoc].[Id] FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 1, '') ,LTRIM(STR(ISNULL([F1].[Id],[F2].[Id]))) + REVERSE(SUBSTRING(REVERSE(ISNULL([F1].[Name],[F2].[Name])), 0, CHARINDEX('.',REVERSE(ISNULL([F1].[Name],[F2].[Name]))) + 1)) AS [crs_management_incoming_document] ,[S].[Name] AS [status] FROM [ELMA].[dbo].[IncomingDoc] LEFT OUTER JOIN [ELMA].[dbo].[Contractor] ON [ELMA].[dbo].[Contractor].[Id] = [ELMA].[dbo].[IncomingDoc].[Contragent] LEFT OUTER JOIN [ELMA].[dbo].[Contact] ON [ELMA].[dbo].[Contact].[Id] = [ELMA].[dbo].[IncomingDoc].[Contact] LEFT JOIN [ELMA].[dbo].[User] AS [U1] ON [U1].[Id] = [ELMA].[dbo].[IncomingDoc].[To] LEFT JOIN [ELMA].[dbo].[User] AS [U2] ON [U2].[Id] = [ELMA].[dbo].[IncomingDoc].[ForwardTo] LEFT JOIN [ELMA].[dbo].[Project] ON [ELMA].[dbo].[Project].[Id] = [ELMA].[dbo].[IncomingDoc].[Project] LEFT JOIN [ELMA].[dbo].[OutgoingDoc] ON [ELMA].[dbo].[OutgoingDoc].[Id] = [ELMA].[dbo].[IncomingDoc].[OutgoingDoc] LEFT JOIN [ELMA].[dbo].[DocumentVersion] AS [DV1] ON [DV1].[DocumentId] = [ELMA].[dbo].[IncomingDoc].[Id] AND [DV1].[Status] = 2 AND ISNUMERIC([DV1].[File]) = 1 LEFT JOIN [ELMA].[dbo].[DocumentVersion] AS [DV2] ON [DV2].[DocumentId] = [ELMA].[dbo].[IncomingDoc].[Id] AND [DV2].[Status] = 2 AND ISNUMERIC([DV1].[File]) = 0 LEFT JOIN [ELMA].[dbo].[FS_FILES] AS [F1] ON [F1].[Id] = [DV1].[File] LEFT JOIN [ELMA].[dbo].[FS_FILES] AS [F2] ON [F2].[Uid] = [DV2].[File] LEFT JOIN [ELMA].[dbo].[Document] ON [ELMA].[dbo].[Document].[Id] = [ELMA].[dbo].[IncomingDoc].[Id] LEFT JOIN [ELMA].[dbo].[LifeCycleStatus] AS [S] ON [S].[Id] = [ELMA].[dbo].[Document].[Status] WHERE --[ELMA].[dbo].[IncomingDoc].[Subj] NOT LIKE '%' AND [ELMA].[dbo].[IncomingDoc].[Subj] NOT LIKE 'test%' [ELMA].[dbo].[IncomingDoc].[Id] > 12193 ORDER BY [ELMA].[dbo].[IncomingDoc].[ReceiveDate]
      
      







ところで、状況はデータとともにすべてのファイルをアップロードおよびインポートする必要があるという事実によって複雑になりました。

完全な驚きは、ある時点でelma開発者がファイルの保存方法を変更したため、2つの異なるリクエストを作成し、それらを結合してファイルをアップロードする必要があったことです。 初めてアップロードしようとしたときに問題が発生しました。 一部のファイルの名前が繰り返され、互いに上書きされました。 idを追加して、リクエストの宛先ファイルの名前を変更する必要がありました。 さらに、実際には、ファイルとその名前をeasla.comに転送し、追加データをファイルとともに保存する必要がありました。 また、ファイル名に入力する必要がありました。 したがって、最終的なファイル名は、id data filename.extという原則に従って形成されました。 elmaはファイルを別のディレクトリに保存するため、クエリ結果は、適切な場所にファイルをアップロードするためのbatファイルに変換される予定でした。 最終的に、受信ドキュメントのファイルをアップロードするために、次のリクエストを受け取りました。

ELMA_export_incoming_files.sql
 SELECT 'copy "\\ssv11\c$\ELMA3-Standart.cfg\UserConfig\Files\' + [FNAME] + '" "c:\temp\elma\incoming\' + REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(ISNULL([ENDNAME],[FNAME]),'«',''),'»',''),'','-'),'.zip.zip','.zip'),'.docx','.docx'),' ',' ') + '"' FROM ( SELECT [ELMA].[dbo].[IncomingDoc].[Id] AS [Id], [ELMA].[dbo].[IncomingDoc].[Subj] AS [Subj], [ELMA].[dbo].[IncomingDoc].[ReceiveDate] AS [RD], LTRIM(STR([F0].[Id])) + REVERSE(SUBSTRING(REVERSE([F0].[Name]), 0, CHARINDEX('.',REVERSE([F0].[Name])) + 1)) AS [FNAME], LTRIM(STR([F0].[Id]) + ' ' + [Name]) AS [ENDNAME] FROM [ELMA].[dbo].[IncomingDoc] LEFT JOIN [ELMA].[dbo].[IncomingDoc_DocAttachments] ON [ELMA].[dbo].[IncomingDoc_DocAttachments].[Parent] = [ELMA].[dbo].[IncomingDoc].[Id] LEFT OUTER JOIN [ELMA].[dbo].[FS_FILES] AS [F0] ON [F0].[Uid] = [ELMA].[dbo].[IncomingDoc_DocAttachments].[DocAttachment] UNION SELECT [ELMA].[dbo].[IncomingDoc].[Id] AS [Id], [ELMA].[dbo].[IncomingDoc].[Subj] AS [Subj], [ELMA].[dbo].[IncomingDoc].[ReceiveDate] AS [RD], LTRIM(STR(ISNULL([F1].[Id],[F2].[Id]))) + REVERSE(SUBSTRING(REVERSE(ISNULL([F1].[Name],[F2].[Name])), 0, CHARINDEX('.',REVERSE(ISNULL([F1].[Name],[F2].[Name]))) + 1)) AS [FNAME], NULL AS [ENDNAME] FROM [ELMA].[dbo].[IncomingDoc] LEFT JOIN [ELMA].[dbo].[DocumentVersion] AS [DV1] ON [DV1].[DocumentId] = [ELMA].[dbo].[IncomingDoc].[Id] AND [DV1].[Status] = 2 AND ISNUMERIC([DV1].[File]) = 1 LEFT JOIN [ELMA].[dbo].[DocumentVersion] AS [DV2] ON [DV2].[DocumentId] = [ELMA].[dbo].[IncomingDoc].[Id] AND [DV2].[Status] = 2 AND ISNUMERIC([DV1].[File]) = 0 LEFT JOIN [ELMA].[dbo].[FS_FILES] AS [F1] ON [F1].[Id] = [DV1].[File] LEFT JOIN [ELMA].[dbo].[FS_FILES] AS [F2] ON [F2].[Uid] = [DV2].[File] ) AS [F] WHERE [FNAME] IS NOT NULL ORDER BY [RD]
      
      







csvファイルをダウンロードし、すべての着信ファイルをダウンロードしました。 手順が長かったのは、 合計ファイルサイズは数ギガバイトでした。 1000レコードのデータをインポートするのは良いことです。なぜなら、 オーバーレイなしではできませんでした。 必然的に10〜15個のエラーが表面化しました。 プレビューを使用して、インポート手順の前にエラーを識別することができました。 とても快適です。 一般に、1000ごとに予備的な準備が必要でした。

すべての発信ドキュメントを同じ方法でインポートしました。

その後、ファイル名を変換する手順がオブジェクトに書き込まれました。 彼女はeasla.comのrevdataファイルに転送されたIDとデータを削除しました 。 したがって、アプリケーションファイルは元のfilename.ext名を受け取りました。

 function updateAttachmentsFileName() { $files = cobjectref()->attributeref('crs_management_incoming_attachments')->availableFiles(); foreach ($files as $f) { $parts = explode(' ', $f->nowname, 2); if (count($parts) == 2) { $f->nowname = $parts[1]; $f->save(); } } }
      
      





特に着信レターについては、発信ドキュメントへのリンクの説明を識別子で置き換える手順が作成されました。

 function updateOutgoing() { if (empty(cobjectref()->attributeref('crs_management_incoming_outgoing')->value)) return; $outgoing_doc = selectAll( 'crs_management', 'crs_management_outgoing', array(), array('crs_management_outgoing_regnum'=>cobjectref()->attributeref('crs_management_incoming_outgoing')->value) ); if (empty($outgoing_doc)) return; cobjectref()->attributeref('crs_management_incoming_outgoing')->value = $outgoing_doc['id']; }
      
      







これらの手順の動作を確認した後、オブジェクトのバッチ更新を開始しました。 ゆっくりだが確実に、 easla.comはすべての施設を更新しました! その後、受信ドキュメントの送信ドキュメントを参照する属性タイプを「String」から「Object」に変更して、オブジェクトの識別子がオブジェクトになるようにしました。

したがって、 easla.comはファイルの名前を変更し、受信ドキュメントと送信ドキュメント間の相互参照を整理しました

一般に、輸出入手続きには約3営業日かかりました。 インターネットチャネルが無料だった夜に、ファイルがeasla.comダウンロードさました。 データの整合性を心配することなく、古い文字をすぐにインポートできるため、1000個のデータのインポートも便利でした。 そして、「戦闘」の開始前にのみ、残りの数百文字をロードしてインポートしました。

彼は2014年末に移行し、2015年1月12日に記載されているすべてのビジネスプロセスを運用しました。

1年以上が経過しました。 手紙の総量は2万を超えました。 タスクの数が1万を超えました。 メインメニューの最新データは次のとおりです。





まとめ



私は一年前にすべてを正しかったと自信をもって言うことができます。 主な利点は次のとおりです。



現在、他のプロセスも開発されています:タスク管理、承認、下請け。 以前elmaでやることが恐れられていたすべてが 、現在easla.comで行われています



PS記事を反広告のエルマと見なさないでください。 このシステムは私たちには向いていませんでしたが、他の人が私たちのように「ジュースを絞り出さない」なら他の人に向いているかもしれません。



All Articles