記事"グラフィカルインタフェースX:リストとテーブルの高度な管理コードの最適化(ビルド7)"についてのディスカッション - ページ 11

 

テーブルを更新する方法がまだ理解できていない。

テーブルには動的なデータがあり、タイマーで更新する必要があります。

Clear()メソッドでクリアしようとするとエラーが出ます:

 invalid pointer access in 'Element.mqh' (106,70)

どうやって更新するのですか?記事のどこにも例がありません。すべての記事で、テーブルは静的データで満たされています。

 
Juer:

どのようにテーブルを更新するのか、私は理解していない......。

テーブルに動的なデータがあるので、タイマーで更新する必要がある。

Clear()メソッドでクリアしようとすると、エラーが出る:

どうやって更新するのですか?記事のどこにも例がありません。すべての記事で、テーブルは静的データで満たされています。

 
Anatoli Kazharski:

ありがとう。ただし、これはソートを考慮していません。

ソートすると、行の位置が変わる可能性がある......。

 
Juer:

ありがとう。ただし、それはソーティングを考慮していない。

ソートすると、行の位置が変わることがあります。

ソートは自分でコントロールできます。この目的のためにCTable::SortData()というパブリックメソッドがあります。

CTable クラスの例と最新バージョンはこちら:EasyAndFastライブラリの更新

 
Anatoli Kazharski:

ソートは自分でコントロールできます。そのためのパブリック・メソッドCTable::SortData() があります。

CTable クラスの例と最新バージョンはこちら:EasyAndFastライブラリの更新

まだ不明な点があります。テーブル内のいくつの行が空でないかを決定するメソッドがありません。オープンオーダーの情報をテーブルにアップロードしています。注文は表示されたり閉じられたりします。テーブルのすべての値を毎回調べて、チケットで比較しなければならない...。不便ですが、可能です。

また、ソートについても教えてください。トレード・タブにある行と同じような行をテーブルに作る必要があります。オープンポジションの利益、手数料などをまとめた行です。つまり、この行の列はテーブルと同じになりますが、合計値が表示されます。そこで、この行をリストの最初に配置し、ソートが適用されないようにするにはどうすればよいでしょうか?

 
Juer:

まだはっきりしない。テーブル内の何行が空でないかを判断する方法はありません。私は未決済注文の情報をテーブルにアップロードしています。注文は表示されたり閉じられたりします。テーブルのすべての値を毎回調べて、チケットで比較しなければなりません。不便ですが、可能です。

...

自分で行を調べて、空かどうかを確認してください。

GUIでExpert Advisorを取引する:機能で埋める(パートII)」の記事で、この実装方法を詳しく説明しています。

Juer

...

また、ソートについても教えてください。テーブルの中に、トレード・タブの行と同じような行を作りたいのです。オープンポジションの利益や手数料などをまとめた行です。つまり、この行の列はテーブルと同じになりますが、合計値が表示されます。では、この行をリストの最初に置き、ソートを適用しないようにするにはどうすればよいでしょうか?

ライブラリにはそのような可能性はありません。オプションとして、最初の表の上に1行のヘッダーのない2番目の表を作成し、そこに合計値を出力することができます。

 
Anatoli Kazharski:

自分でラインを通って、空席があるかどうかを確認する。

GUIでExpert Advisorを取引する:機能で埋める(パートII)」の記事で、どのように実装できるかを詳しく説明しています。

ライブラリにはこの機能はありません。オプションとして、最初の表の上に1行のヘッダーのない2番目の表を作成し、そこに合計値を出力することができます。

記事の例では、やはり行の数は一定ですが、私のは動的です。しかし、私はそれを手作業で行わなければならないことに気づいた。

上記の2つ目のテーブルも悪い解決策ではありませんが、メインテーブルの列の幅を変更する場合はどうすればいいのでしょうか?2番目のテーブルと同期させる方法は?

もうひとつ質問です。最初のカラムは単にレコードの通し番号です。これはソートの対象にはなりません。あるカラムをソートしないようにする方法はありますか?

 
Juer:

記事の例では、やはり行数は一定ですが、私のものは動的です。でも、手作りで何が悪いんだ?

どこに行数が一定だと書いてあった?ポジションの 数や使用される文字の数は変化し、その変化は表に反映されます。


ジュアー

上から2番目の表は悪くない解決策だけど、メインの表の列幅を変えるのは......?どうやって2番目のテーブルと同期させるのですか?

もうひとつ質問です。最初のカラムは単にレコードの通し番号です。これはソートの対象にはなりません。あるカラムをソートしないようにする方法はありますか?

いいえ、方法はありません。

 
Anatoli Kazharski:

行数が一定であることをどこで確認しましたか?ポジション 数と使用文字数は変化し、その変化は表に反映される。

正直なところ、どのようにポジションを更新しているのかよくわかりません。文字テーブルを更新するには、すべての行を削除すればいいのですね。しかし、ポジションテーブルがどのように更新されるのかがまだ理解できません:

//+------------------------------------------------------------------+
//| ポジションテーブルに値を設定する
//+------------------------------------------------------------------+
void CProgram::SetValuesToPositionsTable(string &symbols_name[])
  {
//--- 範囲外をチェックする
   uint symbols_total =::ArraySize(symbols_name);
   uint rows_total    =m_table_positions.RowsTotal();
   if(symbols_total<rows_total)
      return;
//--- 表に指標を表示しよう
   for(uint r=0; r<rows_total; r++)
     {
      int    positions_total =PositionsTotal(symbols_name[r]);
      double pos_volume      =PositionsVolumeTotal(symbols_name[r]);
      double buy_volume      =PositionsVolumeTotal(symbols_name[r],POSITION_TYPE_BUY);
      double sell_volume     =PositionsVolumeTotal(symbols_name[r],POSITION_TYPE_SELL);
      double pos_profit      =PositionsFloatingProfitTotal(symbols_name[r]);
      double buy_profit      =PositionsFloatingProfitTotal(symbols_name[r],POSITION_TYPE_BUY);
      double sell_profit     =PositionsFloatingProfitTotal(symbols_name[r],POSITION_TYPE_SELL);
      double average_price   =PositionAveragePrice(symbols_name[r]);
      string deposit_load    =::DoubleToString(DepositLoad(false,average_price,symbols_name[r],pos_volume),2)+"/"+
                              ::DoubleToString(DepositLoad(true,average_price,symbols_name[r],pos_volume),2)+"%";
      //--- 設定値
      m_table_positions.SetValue(0,r,symbols_name[r]);
      m_table_positions.SetValue(1,r,(string)positions_total);
      m_table_positions.SetValue(2,r,::DoubleToString(pos_volume,2));
      m_table_positions.SetValue(3,r,::DoubleToString(buy_volume,2));
      m_table_positions.SetValue(4,r,::DoubleToString(sell_volume,2));
      m_table_positions.SetValue(5,r,::DoubleToString(pos_profit,2));
      m_table_positions.SetValue(6,r,::DoubleToString(buy_profit,2));
      m_table_positions.SetValue(7,r,::DoubleToString(sell_profit,2));
      m_table_positions.SetValue(8,r,deposit_load);
      m_table_positions.SetValue(9,r,::DoubleToString(average_price,(int)::SymbolInfoInteger(symbols_name[r],SYMBOL_DIGITS)));
      //--- 色を設定する
      m_table_positions.TextColor(3,r,(buy_volume>0)? clrBlack : clrLightGray);
      m_table_positions.TextColor(4,r,(sell_volume>0)? clrBlack : clrLightGray);
      m_table_positions.TextColor(5,r,(pos_profit!=0)? (pos_profit>0)? clrGreen : clrRed : clrLightGray);
      m_table_positions.TextColor(6,r,(buy_profit!=0)? (buy_profit>0)? clrGreen : clrRed : clrLightGray);
      m_table_positions.TextColor(7,r,(sell_profit!=0)?(sell_profit>0)? clrGreen : clrRed : clrLightGray);
     }
  }

理解できないことがあります。シンボルの数がテーブルの行数より少なければ、更新しないのですか?

私はティックごとに実際に値を更新する必要があります。毎回すべての行を削除し、再度テーブルを埋めるのが正しいのでしょうか?

 

Juer:

各目盛りの値を実際に更新する必要があります。すべての行を削除して、その都度テーブルを埋め直すのが正しいのでしょうか?

値を更新するだけなら、何も削除する必要はありません。

もしテーブルの行数を変更する必要があるのであれば、1つの方法を示します。

2番目の方法は、CTable::Rebuilding()メソッドを使用することです。しかし、その場合、いくつかのテーブルのプロパティ(ヘッダー、列幅など)を新たに設定する必要があります。