1Cでのプログラム設定のプレゼンテーション。 片道



こんにちは。

この記事では、1Cの設定での私の経験、つまりプレゼンテーションと保存についてお話したいと思います。 この方法は、特定の構成に関連付けられていないか、単に設定を構成オブジェクトに保存したくない外部処理およびレポートに特に関連しています。 提案された方法には特別な技術的な発見は含まれていません。標準ソリューションのアプリケーションをよりポータブルで整然とするだけです-すべての退屈で骨の折れる作業を1回行うことができ、その後、結果のテンプレートをすべてのプロジェクトで最小限の変更で使用できます。 メソッドの本質はまさにそれです。



1C(ソース)のプログラムのさまざまな例についてインターネットを閲覧しているときに、ほとんどの場合、設定を操作する方法はかなりずさんであることにしばしば気付きました。 標準ルーチン( SaveValueRestoreValue )は、コード内のあらゆる場所で使用され、決してグループ化されません。 格納されている値ごとに、そのような値が数百ある場合でも、データベースに個別の識別子が作成されます(上記のルーチンの文字列パラメーター)。 特に明らかになっているのは、設定値を大量に編集するダイアログボックスの実装です。 それぞれそのようなウィンドウを開くときと閉じるときの長い文字列の呼び出し( RestoreValueSaveValue )。 このアプローチは原則として理解可能です-まず、開発者は特定の問題の解決に集中しますが、いつものように時間はありません。設定の操作は通常の算術式の操作とほぼ同じ方法で認識されます-これらの呼び出しは必要に応じてコードに挿入されます もちろん、開発者が気にしなければ、誰が気にします。 ただし、プログラムが大規模な変更を受ける場合-数十個の値を設定に追加するだけでなく(ほとんどの場合に行われます)、何かを削除し、いくつかのパラメータ(値タイプ)の値を変更します、はいパラメーターの値をリセットするだけです(たとえば、テスト目的で)-個々のパラメーターの束でこのようなアクションを実行するのは非現実的になります-デバッガーの下ではなく、頭の中ですべてのテストを簡単に実行できます。



しかし、設定を操作するためのツールを作成するために一度だけ-ユニバーサルでポータブルな場合はどうでしょうか? プログラム間でコピーすることをためらうことなく簡単に行うことができます(もちろん、特定のパラメーターの実際のセットを変更します)。 試してみましょう...



実装では、前述の「 1Cの自家製OOP 」という技術的手法を使用します。 プログラム設定のリポジトリを個別のクラスとして作成しましょう(設定のグループを何らかの方法で分割する必要がある場合、プログラムはそのようなストレージクラスを複数持つことができます)。 標準呼び出し( RestoreValueSaveValue )は、プログラム全体で1回使用されます。 リポジトリのすべてのコンテンツはXML形式にシリアル化されます 。 したがって、値の「フラットセット」( INIファイルなど)だけでなく、分岐構造の表現を提供することもできます。 ただし、この例では、単純化のために非常に「フラットセット」を検討します。 セットの構造は重要ではありません。



たとえば、次のパラメーターセットがあるとします。

役職 種類 初期値
Param1 0
Param2 ひも 「」
Param3 リファレンスリファレンス。 未定義
Param4 ブール値
Param5 日付 未定義


従来は、特定の構成に接続されないように、最も単純なタイプのみを考慮しています。 しかし、文字列へのシリアル化と文字列からより複雑なオブジェクトの復元のアイデアを示すために、参照タイプ(参照「 命名法 」は多くの典型的な構成にあります)も考慮します。



クラスのフィールド構造は次のようになります。

 _()  =  ; .("ChangeInfo", ); //       .("ErrMsg", ""); //     //  ,    .("Set_1", ); //   1 .("Set_2", ); //   2 .("Set_3", ); //   3 .("Set_4", ); //   4 .("Set_5", ); //   5  ; 
      
      





ご覧のとおり、直接ターゲットのパラメーターに加えて、クラスにはサービスフィールドもあります。 ターゲットフィールドの名前には特別な合意があります-接頭辞「 Set_ 」で始まります。 これは、ループ内で構造のフィールド(クラスオブジェクトをシミュレート)をトラバースするときに、ターゲットフィールドとサービスフィールドを自動的に区別するために必要です。 外部では、これらの名前の変更は表示されず、通常のパラメーター名が使用されます(「 Set_ 」プレフィックスなし)。



次に、このクラスのコードを完全に示します。

クラス設定
 //////////////////////////////////////////////////////////////////////////////// //    () //       // // : // . // : //    //  _()   =  ; .("ChangeInfo", ); //       .("ErrMsg", ""); //     //  ,    .("Set_1", ); //   1 .("Set_2", ); //   2 .("Set_3", ); //   3 .("Set_4", ); //   4 .("Set_5", ); //   5  ;  //    // // : // . // : // () -     //  _()   = _(); //    _SetDefAttr();  ;  //    -   // // : //  -    //  _()   //      . // // : //  -    //  _SetDefAttr()  .ErrMsg = ""; .Set_1 = 0; .Set_2 = ""; .Set_3 = ; .Set_4 = ; .Set_5 = ;  //     2   1. //     1  . // // : // 1 -    // 2 -      //  _Assign(1, 2)   (1 <> )  (2 <> )  (_IsEqual(1, 2) = )      1   (., "Set_") = 1  //      (  ) 1[.] = 2[.]  ; 1.ChangeInfo =    //      . // // : // 1 -    // 2 -      //  // ,   2   ,   //  1   -    //  _IsEqual(1, 2)   = ;  (1 <> )  (2 <> )   = ;     1   (., "Set_") = 1  //      (  )  . <> 2[.]   = ;    ;  =  ;    //      . // // : //  -    //  _GetErrorMsg()   .ErrMsg  //     . // // : //  -    // PrmName -   //  //   PrmName  ,      //  _GetPrm(, PrmName)   = ; .ErrMsg = "";   = ["Set_" + PrmName];  .ErrMsg = "_GetPrm:   : " + PrmName; ;    //     . // // : //  -    // PrmName -   // PrmVal -    //  _SetPrm(, PrmName, PrmVal)  .ErrMsg = "";   ["Set_" + PrmName] <> PrmVal  ["Set_" + PrmName] = PrmVal; .ChangeInfo =    .ErrMsg = "_SetPrm:   : " + PrmName;   //      (   ). // // : //  -    // PrmName -   //  //    PrmName  ,      //  _GetPrmStrVal(, PrmName)   = ; .ErrMsg = "";   = ["Set_" + PrmName]; //        PrmName = "1"  //   №1 ()  = (, "=0; =''")  PrmName = "2"  //   №2 ()  =   PrmName = "3"  //   №3 (.)  ()   = .   =    PrmName = "4"  //   №4 ()  = (, "=0; =1")  PrmName = "5"  //   №5 ()  = (, "=""yyyyMMddHHmmss""")   .ErrMsg = "_GetPrmStrVal:   : " + PrmName + " : " + ().; ;    //          // (       ). // // : //  -    // PrmName -   // StrPrmVal -      //  _SetPrmFromStrVal(, PrmName, StrPrmVal)  .ErrMsg = "";   = ; //        PrmName = "1"  //   №1 ()  = (StrPrmVal)  PrmName = "2"  //   №2 ()  = StrPrmVal  PrmName = "3"  //   №3 (.)  (StrPrmVal)   = ..(StrPrmVal);   ()   =     PrmName = "4"  //   №4 ()  = ((StrPrmVal))  PrmName = "5"  //   №5 ()  = (StrPrmVal) ; //    ["Set_" + PrmName] <>   ["Set_" + PrmName] = ; .ChangeInfo =    .ErrMsg = "_SetPrmFromStrVal:   : " + PrmName + " : " + ().;   //      //    // // : //  -    //  //     //  _GetChangeInfo()   .ChangeInfo  //       //     // // : //  -    // ChangeInfo -     //  _SetChangeInfo(, ChangeInfo)  .ChangeInfo = ChangeInfo  //    XML-,    XML. // // : //  -    // XML -    XML- //  // ,       -    //  _LoadSettingsFromXML(, XML)   = ; //      .ErrMsg = "";  XML <>    //   _SetDefAttr(); //   _settings = ;  = "";  XML.()   XML. = "settings"   (_settings = )  (XML. = XML.)  //      _settings =   //      _settings = ;  = "";     _settings  //       XML. = XML.  //      = XML.;  XML. = XML.   ( <> "")  (.("Set_" + ))  _SetPrmFromStrVal(, , XML.);   XML. = XML.   = ""    ; //    .ErrMsg = ""  .ChangeInfo = ; //     =  //      //    XML .ErrMsg = "_LoadSettingsFromXML: " + ().;   //    .ErrMsg = "_LoadSettingsFromXML:   "; ;    //    XML-,   XML. // // : //  -    // XML -    XML- //  // ,       -    //  _SaveSettingsToXML(, XML)   = ; //      .ErrMsg = "";  XML <>    //   XML.XML(); XML.("settings"); //      Item     (Item., "Set_") = 1   = (Item., 5);   <> ""  XML.(); XML.((_GetPrmStrVal(, ))); XML.() //    ; //   XML- XML.(); // settings  .ErrMsg = ""  .ChangeInfo = ; //     =  //      //    XML .ErrMsg = "_SaveSettingsToXML: " + ().;   //    .ErrMsg = "_SaveSettingsToXML:   "; ;    //    XML-,    XMLStr. // // : //  -    // XMLStr -   XML- //  // ,       -    //  _LoadSettingsFromXMLStr(, XMLStr)   = ; //      .ErrMsg = "";  (XMLStr <> )  (XMLStr <> "")   XML =  XML(); XML.(XMLStr); //     = _LoadSettingsFromXML(, XML);  //    XML .ErrMsg = "_LoadSettingsFromXMLStr: " + ().;   //    .ErrMsg = "_LoadSettingsFromXMLStr:   "; ;    //    XML-,   XMLStr. // // : //  -    // XMLStr - ,   XML- //  // ,       -    //  _SaveSettingsToXMLStr(, XMLStr)   = ; //      .ErrMsg = "";  XML =  XML(); XML.(); //     = _SaveSettingsToXML(, XML); //  XML-       XMLStr = XML.();   //    XML .ErrMsg = "_SaveSettingsToXMLStr: " + ().; ;    //    XML- FName. // // : //  -    // FName -    XML- //  // ,       -    //  _LoadSettingsFromFile(,  FName)   = ; //      .ErrMsg = "";  (FName <> )  (FName <> "")   XML =  XML(); XML.(FName); //     = _LoadSettingsFromXML(, XML);  //    XML .ErrMsg = "_LoadSettingsFromFile:" + ().;   //    .ErrMsg = "_LoadSettingsFromFile:   "; ;    //    XML-,   FName. // // : //  -    // FName -  ,   XML- //  // ,       -    //  _SaveSettingsToFile(,  FName)   = ; //      .ErrMsg = "";  (FName <> )  (FName <> "")   XML =  XML("windows-1251",,,, " "); XML =  XML(); XML.(FName, XML); //     = _SaveSettingsToXML(, XML); //   XML.();  //    XML .ErrMsg = "_SaveSettingsToFile: " + ().;   //    .ErrMsg = "_SaveSettingsToFile:   "; ;   
      
      







当然、パラメータ値を取得および設定するには、サブルーチン「 SetupProg_GetPrm 」および「 SetupProg_SetPrm 」をそれぞれ使用する必要があります。 クラスを模倣する構造の要素に値を単純に割り当てることはできません。



これは設定セットの機能であり、私の意見ではこれで十分です。 あなたはあなた自身の自由意志のサブルーチンでそれを拡張することができます。



この設定リポジトリの使用方法は次のとおりです。

 //  -   " " .   //        . // // : // . //  () //     = _(); XMLStr = ("_");  XMLStr <>   _LoadSettingsFromXMLStr(, XMLStr) ;  //  -   " " .   //    . //   . // // : // . //  () //     _GetChangeInfo()  XMLStr = ""; _SaveSettingsToXMLStr(, XMLStr); ("_", XMLStr); ; _();  //  -   ""  . //     . // // : //  -   -  //  () ("1 = " + _GetPrm(, "1")); ("2 = " + _GetPrm(, "2")); ("3 = " + _GetPrm(, "3")); ("4 = " + _GetPrm(, "4")); ("5 = " + _GetPrm(, "5")); 
      
      





次に、設定セットを編集するためのダイアログボックスのコードを分析します。 サンプルパラメータセットの場合、次のようになります。







適切なコントロールをフォームに配置して、パラメーターを表示および編集します。 フォームの詳細を作成しましょう-各パラメーターは個別であり、コントロールをそれらにアタッチします。 設定リポジトリ( NastrProgrクラスのオブジェクト)とこれらの詳細の間で既にデータを交換します。

このフォームのモジュールのソースコードは次のとおりです。

モジュールコードフォーム設定パラメーター
 //////////////////////////////////////////////////////////////////////////////// //      ; //     //////////////////////////////////////////////////////////////////////////////// //    //  -   " " .   //        . // // : // . //  () //        = .1  //  -   ""  OK. //      . // // : //  -  //  ()  CheckInput()  .(.)   //////////////////////////////////////////////////////////////////////////////// //   //           . // // : //  // : // ,       -    //  CheckInput()  = ; ErrMsg = ""; //    -  // ******************************** //       ErrMsg = ""  //    ReadSettingsFromInterf(); //       =   (ErrMsg) ;    //     . // // : //  //  LoadSettingsToInterf()   <>   //   1 = _GetPrm(, "1"); 2 = _GetPrm(, "2"); 3 = _GetPrm(, "3"); 4 = _GetPrm(, "4"); 5 = _GetPrm(, "5");   //     . // // : //  //  ReadSettingsFromInterf()   <>   //   _SetPrm(, "1", 1); _SetPrm(, "2", 2);  (3)  _SetPrm(, "3", 3)  _SetPrm(, "3", ) ; _SetPrm(, "4", 4); _SetPrm(, "5", 5);   //////////////////////////////////////////////////////////////////////////////// //    //         //   . // // : //  -   . // : // ,        ,    //   //  SetMainSettingsDlg()   = ; //       <>   //     = ; //      LoadSettingsToInterf(); //    .() = .  //     =   ;   
      
      







そして、これがこのダイアログボックスの使用方法です(メインフォームウィンドウから)。

 //  -   ""  . //      . // // : //  -   -  //  () //      = _(); _Assign(, ); _SetChangeInfo(, ); //      = .("", );  .SetMainSettingsDlg()  //     _IsEqual(, )  //      _Assign(, );  ; _() 
      
      





それがすべての方法です。複雑なことは何もありません。しかし、個人的には、明確で組織的なアプローチが好きです。さて、再び移植性。結局のところ、この設定リポジトリを完全に考えずに他のリポジトリに変えるには、次のルーチンを機械的に書き換えます。

  _()  _SetDefAttr()  _GetPrmStrVal(, PrmName)  _SetPrmFromStrVal(, PrmName, StrPrmVal)
      
      





考慮されているプログラムのソースコード(1C 8.2の処理)をここからダウンロードします



以上です。 皆さん、頑張ってください。 じゃあね



All Articles