
こんにちは。
今日は、ユーザーに情報メッセージを発行するためのサブシステムの実装に焦点を当てます。 ユーザーに何かを通知する標準的な方法は、「 レポート 」手順を使用することです。 ただし、場合によっては、プラットフォームメッセージのメインリストとその出力が混雑しないように、個別のリストを作成したいと思います。 さまざまなメッセージに色を付けることもできます(たとえば、タイプに応じて)。 一般的に、どうやってそれを成し遂げたかをお話しします。 この記事に記載されているソリューションは、適応なしでプログラムに統合できます。
バックグラウンド。
かつて、 Perforceバージョン管理システム、つまりグラフィカルクライアントを使用して、メインプログラムウィンドウの下部にある複数行のメッセージ出力フィールドという便利なインターフェイス要素に注目しました。 ユーザーがシステムサーバーに呼び出しを行った後、このフィールドにテキストメッセージが追加され、クライアントとサーバー間の対話プロセス(実行された具体的なアクションと実行結果)が説明されました。 さまざまなグラフィカルIDE(Delphi、C ++など)の前後でまったく同じシステムを見ましたが、そのコンソールプログラム(コンパイラまたはバージョン管理クライアント)のメッセージ出力ウィンドウは、Perforceがこのような印象を与えた理由はわかりません。 )、そのシェルはグラフィックプログラムです。 しかし、ちなみに、この記事はPerforceに関するものではありません。メッセージの複数行出力を使用して、長時間の作業を実行すると便利だと思います。 メッセージの大きなリストを取得することは、この作業の最後にある単一のMessageBoxよりもはるかに優れています(より有益です)。 ところで、アンチウイルスプログラムでも同様のアプローチが見られます。
比較的長いデータ処理プロセスを実行するプログラムを実装することにより、独自のメッセージサブシステムを作成するように求められました(つまり、ユーザーが[ 実行 ]ボタンをクリックしてから、プロセスの実行中に比較的話せば数分待つことができます)。 同様のプログラム(処理)は、標準の1C構成でも使用できます(基本的に、これらはさまざまなアップロード/ダウンロードです)。 標準のプラットフォームメッセージウィンドウ(「 レポート 」手順で情報が表示される)は、私には適していませんでした。 処理に関連するメッセージをグループ化し、他のメッセージと混合しないようにしました。 また、万一の場合に備えて、メッセージリストを何らかの方法で(ウイルス対策で行われているようにテキストファイルに)保存することも望んでいました。 最も重要なことは、さまざまな種類のメッセージ(情報、警告、エラーメッセージ)を作成することでした。 まあそれに応じて、さまざまな色でそれらをペイントします。
検討中の例では、メッセージ出力テーブル( テーブルフィールドインターフェイス要素)は次のようになります。

実装の説明。
一般に、ここで何が起こったのかを説明します。 実装のために、1Cテクノロジーで再びOOPを使用します(方法については、 ここで詳しく説明します )。 したがって、「クラス」が作成されます:「 プログラムメッセージ 」。
将来的には、説明する際に、外部処理を行っていると想定します。
メッセージのステータスを表示するアイコンが必要になります。 対応するBMPファイル(この記事に添付)からリソース(「バイナリデータ」タイプのレイアウト)にダウンロードします。
画像 | ソースファイル名 | レイアウト名 |
---|---|---|
![]() | statok.bmp | PictureMessageStatusOK |
![]() | statwarning.bmp | 画像メッセージステータス警告 |
![]() | staterror.bmp | PictureMessageStatusError |
その後、何らかの方法でこれらの写真を使用するために読み込む必要があります-リソースに変換します。
メインモジュールでは、標準の「Picture」クラスのオブジェクトから構造体の形でグローバル変数「Picture Collection」を定義します。 コレクションを初期化するサブルーチン「Generate the Picture Collection」を作成します。 モジュールの初期化セクションでこのサブルーチンを呼び出します。
また、メッセージにはいくつかの数値タイプ-レベルがあります。 レベル番号は、メッセージがインターフェイスまたはファイルに出力されるときに、左側の空白からのインデントの数に影響します(相互にメッセージのネストのレベルを明確に示すように)。
役職 | 説明 | 数値 |
---|---|---|
TYPE | 未定義の値 | 0 |
TYPE TOTAL_ LEVEL1 | ネストレベル1 | 1 |
TYPE TOTAL_レベル2 | ネストレベル2 | 2 |
TYPE TOTAL_レベル3 | ネストレベル3 | 3 |
各メッセージには特定のステータスがあり、メッセージの内容を正確に示します。
役職 | 説明 | 数値 |
---|---|---|
STATUS_NOTRED | 未定義の値 | 0 |
STATSUBSCH_OK | ネストレベル1 | 1 |
STATSUBSTV_PREDUPR | ネストレベル2 | 2 |
STATUM_ERROR | ネストレベル3 | 3 |
C / C ++( #define )またはPascal( const )で行われているように、型と状態を数値定数として表します。 1Cでは、グローバル構造変数に定数を挿入することで定数をシミュレートします(構造要素のキーは定数のシンボル名であり、構造要素の値は定数の数値です)。
() = ; // .("_", 0); // .("_1", 1); // 1 .("_2", 2); // 2 .("_3", 3); // 3 // .("_", 0); // .("_", 1); // "" .("_", 2); // "" .("_", 3); // ""
また、ミリ秒単位で現在の時刻を取得する必要があります。 これには、COMオブジェクトのグローバル変数としてJavaScriptエンジンを使用します。
メインモジュールで発生したことは次のとおりです。
ソーステキスト
//////////////////////////////////////////////////////////////////////////////// // ; // ; // //////////////////////////////////////////////////////////////////////////////// // JavaScript; // JavaScript /////////////////////////////////////////////////////////////////////////////////////////////////// // // // /////////////////////////////////////////////////////////////////////////////////////////////////// // // // : // . // // : // - // () = ; // .("_", 0); // .("_1", 1); // 1 .("_2", 2); // 2 .("_3", 3); // 3 // .("_", 0); // .("_", 1); // "" .("_", 2); // "" .("_", 3); // "" // , , // . // // : // . // // : // - // () = ; .("", ((""))); .("", ((""))); .("", ((""))); /////////////////////////////////////////////////////////////////////////////////////////////////// // // // /////////////////////////////////////////////////////////////////////////////////////////////////// // JavaScript // , , // . // // : // . // // : // JavaScript , // JavaScript() = ; = COM("MSScriptControl.ScriptControl"); .Language = "javascript"; ; /////////////////////////////////////////////////////////////////////////////////////////////////// // // // /////////////////////////////////////////////////////////////////////////////////////////////////// // , // // : // - // - - // : // // (, ) = ; = - (); > 0 = " " + ; = - 1 ; // , // // : // - // - - // : // // (, ) = ; = - (); > 0 = + " "; = - 1 ; // // // : // // : // 0, // () = 0; JavaScript <> = JavaScript.Eval("new Date().getTime()"); ; ; //////////////////////////////////////////////////////////////////////////////// // - // // = (); // = (); // // JavaScript JavaScript = JavaScript();
メッセージのセットは、次の列を持つ値の表 ( 値表の標準クラス)の形式で存在します。
列名 | データ型 | 予定 |
---|---|---|
TypeMessage | 数 | メッセージのタイプ(レベル)-定数の1つ |
StatusMessage | 数 | メッセージステータスは定数の1つです |
TextMessage | ひも | メッセージの本文。 ここでは、通常、現時点で長時間のプロセスによって実行されるアクションを示します。 |
コメント | ひも | 追加のメッセージテキスト。 ここでは、通常、TextText列に記述されているアクションの結果を示します。 アクションが失敗した場合、同じ列にエラーメッセージが表示されます |
この値のテーブルは、ユーザーインターフェイスの一部の要素(たとえば、 TableFieldクラスのオブジェクト)に既に表示できます。
メッセージセットは、次のメソッドを持つクラスとして実装されます。
メソッドヘッダー | 説明 |
---|---|
関数メッセージ_コンストラクター() | オブジェクトの初期作成。 「Messages」クラスのオブジェクトを返します。 |
メッセージProcedure_UstAtrib(メッセージ、フォーム、TabPole、TabValue) | オブジェクトの属性を設定します。 合格する必要があります:
-メッセージのリストが表示されるフォーム(フォーム)へのリンク。 -メッセージが表示されるTablichnoePol(TabPol)タイプのフォームの要素。 -値の表(TabValue)。メッセージの実際のリストが格納されます。 |
メッセージプロシージャ_初期化(メッセージ) | 値テーブル(Messages_UstAtribプロシージャによって以前に設定された)は初期化されます。 |
プロシージャMessages_Update(メッセージ) | フォーム上のメッセージのリストの強制描画を実行します(以前はMessages_UstAtribプロシージャで設定されていました) |
Message_Add関数(Message、TypeMessage、TextMessage、StatusMessage = Undefined、CommentsMessage = Undefined) | 適切な属性を持つ新しいメッセージをセットに追加します。 助けを借りてメッセージの識別子を返します。このメッセージは将来アクセスできます。 |
メッセージProcedure_Change(メッセージ、メッセージID、タイプメッセージ=未定義、テキストメッセージ=未定義、ステータスメッセージ=未定義、コメントメッセージ=未定義) | 指定された識別子を持つ既存のメッセージの属性を変更します。 |
Message_Deleteプロシージャ(メッセージ、メッセージID) | 対応する識別子を持つ以前に追加されたメッセージを削除します。 |
メッセージProcedure_Clear(メッセージ) | すべてのダイヤルメッセージを削除します。 |
Message_GetType関数(メッセージ、メッセージID) | 指定された識別子を持つ既存のメッセージのType属性を取得します。 |
メッセージProcedure_SetType(メッセージ、メッセージID、タイプメッセージ) | 指定された識別子を持つ既存のメッセージのType属性を設定します。 |
Message_GetStatus関数(メッセージ、メッセージID) | 指定された識別子を持つ既存のメッセージのステータス属性を取得します。 |
メッセージProcedure_SetStatus(メッセージ、メッセージID、ステータスメッセージ) | 指定された識別子で既存のメッセージのステータス属性を設定します。 |
Message_GetText関数(メッセージ、メッセージID) | 指定された識別子を持つ既存のメッセージの「メッセージテキスト」属性を取得します。 |
メッセージProcedure_SetText(メッセージ、メッセージID、メッセージテキスト) | 指定した識別子を持つ既存のメッセージの「メッセージテキスト」属性を設定します。 |
Message_GetComment関数(メッセージ、メッセージID) | 指定された識別子を持つ既存のメッセージのコメント属性を取得します。 |
メッセージProcedure_SetComment(メッセージ、メッセージID、コメントメッセージ) | 指定された識別子を持つ既存のメッセージの「コメント」属性を設定します。 |
メッセージFunction_TextText(タイプメッセージ、ステータスメッセージ) | 指定したステータスのメッセージテキストの色を定義します。 インターフェイスでメッセージを着色するときに使用されます。 |
Message_ColorComment関数(TypeMessage、StatusMessage) | 指定したステータスのメッセージの追加テキスト(コメント)の色を定義します。 インターフェイスでメッセージを着色するときに使用されます。 |
Message_Picture関数(タイプメッセージ、ステータスメッセージ) | 指定したステータスのメッセージのアイコンを定義します。 インターフェイスでメッセージを表示するときに使用されます。 |
関数Message_Save To File(メッセージ) | メッセージセットをテキストファイルに保存します(ファイル名がユーザーに要求します)。 |
したがって、メイン処理モジュールの全文:
モジュールテキスト
//////////////////////////////////////////////////////////////////////////////// // ; // ; // //////////////////////////////////////////////////////////////////////////////// // JavaScript; // JavaScript /////////////////////////////////////////////////////////////////////////////////////////////////// // // // /////////////////////////////////////////////////////////////////////////////////////////////////// // // // : // . // // : // - // () = ; // .("_", 0); // .("_1", 1); // 1 .("_2", 2); // 2 .("_3", 3); // 3 // .("_", 0); // .("_", 1); // "" .("_", 2); // "" .("_", 3); // "" // , , // . // // : // . // // : // - // () = ; .("", ((""))); .("", ((""))); .("", ((""))); /////////////////////////////////////////////////////////////////////////////////////////////////// // // // /////////////////////////////////////////////////////////////////////////////////////////////////// // JavaScript // , , // . // // : // . // // : // JavaScript , // JavaScript() = ; = COM("MSScriptControl.ScriptControl"); .Language = "javascript"; ; /////////////////////////////////////////////////////////////////////////////////////////////////// // // // /////////////////////////////////////////////////////////////////////////////////////////////////// // , // // : // - // - - // : // // (, ) = ; = - (); > 0 = " " + ; = - 1 ; // , // // : // - // - - // : // // (, ) = ; = - (); > 0 = + " "; = - 1 ; // // // : // // : // 0, // () = 0; JavaScript <> = JavaScript.Eval("new Date().getTime()"); ; ; // COMSafeArray // // : // COMSafeArray - COMSafeArray // ( 1) // : // "", // COMSafeArray(COMSafeArray) = ""; (COMSafeArray) = ("COMSafeArray") (COMSafeArray.GetDimensions() = 1) (COMSafeArray.GetLength(0) > 0) = COMSafeArray.(); () = ("") // Windows-1251 UTF-8 ( >= 192) ( <= 223) // - = + 848 ( >= 224) ( <= 239) // - = + 848 ( >= 240) ( <= 255) // - = + 848 ( = 184) // = 1105 ( = 168) // = 1025 ( = 185) // № = 8470 ; // = + () ; /////////////////////////////////////////////////////////////////////////////////////////////////// // // // /////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // () // . // // : // . // : // // _() = ; // .("", ); // .("", ); // .("", ); // .("", ); // . . , (INT) ; // . // // : // // : // () - // _() = _(); ; // - . // // : // - // _() // . // // : // - // - , // - // - // _(, , , ) . = ; . = ; . = // . // // : // - // _() . <> = (10, 0); = (); = ; .(("")); = (, , ,); .(); .(("")); = (, , ); // "" ...("") = ...("", , "", 30) ; // "" ...("") = ...("", , "", 30) ; // "" ...("") = ...("", , "", 200) ; // "" ...("") = ...("", , "", 200) // , // . // , // // : // - // _() . <> = 500; // ( ), = (); (. = ) (. = 0) ( - . >= ) // . = ; ..() // // // : // - ; // - ; // - ; // - ; // - // : // . // . . // _(, , , =, =) = ; (. <> ) ( <> ) ( >= ._1) ( <= ._3) ( <> ) = ..(); . = ; // = ._1 = ._2 = " " + = ._3 = " " + ; // . = ; ( <> ) ( >= ._) ( <= ._) . = ; . = ._; ; . = ; . <> // , // , .. = ; ; _(); = ..(); ; // . , "" // // : // - ; // - ( ); // - ; // - ; // - ; // - // _(, , =, =, =, =) (. <> ) ( <> ) ( >= 0) ( < ..()) = ; // , - ( ) <> ( <> .[].) ( >= ._1) ( <= ._3) .[]. = ; = ; <> <> .[]. // .[]. = ._1 .[]. = ._2 = " " + .[]. = ._3 = " " + ; // .[]. = ; = ; <> <> .[]. ( <> ) ( >= ._) ( <= ._) .[]. = ; .[]. = ._; ; = ; <> <> .[]. .[]. = ; = ; = // , _() // // // : // - // - ( ) // _(, ) (. <> ) ( <> ) ( >= 0) ( < ..()) ..(); _() // // // : // - // _() (. <> ) (..() > 0) ..(); _() // // // : // - // - ( ) // : // , // _(, ) = ; (. <> ) ( <> ) ( >= 0) ( < ..()) = .[]. ; // // // : // - // - ( ) // - // _(, , ) (. <> ) ( <> ) ( >= 0) ( < ..()) ( <> .[].) ( >= ._1) ( <= ._3) .[]. = ; _() ; // // // : // - // - ( ) // : // , // _(, ) = ; (. <> ) ( <> ) ( >= 0) ( < ..()) = .[]. ; // // // : // - // - ( ) // - // _(, , ) (. <> ) ( <> ) ( >= 0) ( < ..()) ( <> .[].) ( <> ) ( >= ._) ( <= ._) .[]. = ; .[]. = ._; ; _() // // // : // - // - ( ) // : // , // _(, ) = ; (. <> ) ( <> ) ( >= 0) ( < ..()) = .[]. ; // // // : // - // - ( ) // - ; // _(, , ) (. <> ) ( <> ) ( >= 0) ( < ..()) ( <> ) ( <> .[].) // .[]. = ._1 .[]. = ._2 = " " + .[]. = ._3 = " " + ; // .[]. = ; _() // // // : // - // - ( ) // : // , // _(, ) = ; (. <> ) ( <> ) ( >= 0) ( < ..()) = .[]. ; // // // : // - // - ( ) // - // _(, , ) (. <> ) ( <> ) ( >= 0) ( < ..()) ( <> .[].) .[]. = ; _() // // // : // - // - // : // // _(, ) = ; = ._1 = Web. = ._2 = Web. = ._3 = Web. ; // // // : // - // - // : // // _(, ) = ; = ._ = Web. = ._ = Web. = ._ = Web. ; // // // : // - // - // : // // _(, ) = ; = ._ = . = ._ = . = ._ = . ; // // // : // - // : // , - // _() = ; // . = // ; // = (.); . = " (*.txt)|*.txt" + "| (*.*)|*.*"; . = " "; . = ; . = ; . = "txt"; . = 0; . = ; .() // // = (., .ANSI); // // = 0; = 0; . = (.); > = ; ; = (.); > = ; ; ; // . = " "; // = ""; // (. <> ) (. <> ._) = ""; . = ._ = ""; . = ._ = ""; . = ._ = ""; ; <> "" = + ; = + (, 14); ; // (. <> ) (. <> "") <> "" = + ; = + (., ); ; // (. <> ) (. <> "") <> "" = + ; = + (., ); ; // <> "" .() ; // .(); = // // (" :" + . + ().); ; //////////////////////////////////////////////////////////////////////////////// // - // // = (); // = (); // // JavaScript JavaScript = JavaScript();
ループの長いプロセスの間、ユーザーインターフェイスはブロックされるため、メッセージの追加または変更の事実はユーザーには表示されないことに注意してください。レンダリングは行われません。レンダリングを強制するには、メッセージを表示するフォームのRefresh()メソッドを呼び出す必要があります。しかし、このメソッドを頻繁に呼び出すと、作業が遅くなります。そのため、時々呼び出すだけで済みます(ただし、ユーザーが遅れに気付かないように短い間隔で呼び出します。この実装では、更新間隔は0.5秒で1回以下です)。更新を実装するには、Messages_Updateクラスのメソッドを使用します。
使用例。
この例では、メッセージセットを表示するフォームは次のようになります。「プロセスを実行」

ボタンの代わりに、実際にはもっと便利なものがあるはずです-ある種のユーザーインターフェイス。 「プロセスの開始」ボタンは、メッセージのリストを埋めることを模倣し、長期的なアクションの実際の実行プロセスでメッセージを表示する方法を示します。フォームの詳細として、値テーブルが作成されます-「メッセージ」。初期化は一切行わず、Messages_クラスの対応するメソッドにパラメーターとして渡すだけで、必要な列が既に作成されます。
= _(); _(, , ., ); _();
「メッセージ」値テーブルを表示するには、「テーブルフィールド」-「メッセージのテーブルフィールド」タイプの視覚コンポーネントをフォームに配置します。TableFieldで列を作成するとき、値テーブル(前述)の次の列を考慮します。
- TypeMessage ;
- ステータスメッセージ。
- テキストメッセージ ;
- KommentariySoobsch。
メイン処理フォームのモジュールのテキスト(メッセージの表示):
フォームモジュールテキスト
//////////////////////////////////////////////////////////////////////////////// // ; // . . . //////////////////////////////////////////////////////////////////////////////// // // - " " . // , . // // : // . // () // = _(); _(, , ., ); _(); // - " " . // . // . // // : // . // () // _() // - "" . // , . // // : // - . // () // = (); = .(1, 100); // = (" ?", ., , , " "); = . // ErrMsg = ""; _(); // _(, ._1, "*** ***"); = ; = 0; // =1 // , 2 = _(, ._2, " " + (, "=0; =''")); // ****************************** // .(0, ) > 0 // , = // , = ; // ****************************** // = ._; = ""; // = ._; = "" // = ._; = "" ; _(, 2, , , , ); // // - ; = + 1 // - ErrMsg = ().; = ; // // _(, ._1, "*** ***"); // _(, ._1, "*** ***", ._, ErrMsg) ; // = ""; = " " = " " ; = + .; = + " " + (, "=0; =''") + " ."; (, , " ") // - "" // . . // // : // - ; // - // - . // (, , ) // "" ... = ; = _(., .); <> ... = ; ... = ; ; // "" (. <> ) (. <> "") = _(., .); <> ... = ; // "" (. <> ) (. <> "") = _(., .); <> ... = // - "" . // . // // : // - . // () = .("", ); .ShowMessagesDlg() // - "" . // . // // : // - . // () _();
メッセージビューフォーム。
メッセージのリストを表示するための別のウィンドウもあります(値テーブルに対応)。大きなリストを分析するのがより便利になるように意図されています(メインダイアログボックスの[メッセージのテーブル]フィールドでは、高さを強く伸ばすことができないため、他のインターフェイス要素が干渉します)。
フォームは、おおよそ次のように見え

ます。フォームモジュールのコードは完全に複雑ではありません。以下がその1つです。
フォームモジュールテキスト
//////////////////////////////////////////////////////////////////////////////// // ; // //////////////////////////////////////////////////////////////////////////////// // // - "" . // . // // : // - . // () _(); // - "" // . . // // : // - ; // - // - . // (, , ) // "" ... = ; = _(., .); <> ... = ; ... = ; ; // "" (. <> ) (. <> "") = _(., .); <> ... = ; // "" (. <> ) (. <> "") = _(., .); <> ... = //////////////////////////////////////////////////////////////////////////////// // // // // : // - . // ShowMessagesDlg() ; <> // = ; .. = .; // .()
メッセージサブシステムのソーステキストと考慮される例(1C 8.2の処理)は、ここからダウンロードできます。
以上です。 皆さん、頑張ってください。 じゃあね
PS
() FireBird 1.:
— () ;
— : ;
— ;
— ;
— , FireBird ( , - ).
(«»):
— ( , );
-クエリパラメータを操作するため(Delphiの場合とほぼ同じようにパラメータを設定および設定できます)。
そしてまた:
-整数と文字列のセットを使用するには(クエリに複数のパラメーターを設定すると便利です)。
-さまざまなFireBirdデータベースへの接続プロファイルの便利なストレージ、およびユーザーインターフェイス(接続プロファイルのセットを編集するためのフォーム)
一般に、面白いと思います。もう一度、幸運を...