喫茶XRAYトップページ


[499] 教えて Result返信 削除
2005/11/9 (水) 21:01:50 Syake
こんばんはマスター

いや〜まいりました。
@メインフォームからサブフォームを開く
Aサブフォームで集計日を指定して集計
 実際の集計はデータモジュールの関数
   :戻り値はレコード型の動的配列変数
B結果を元に集計結果をサブフォームのStringGridに表示
とよく有るPattern。

で、無効なポインタ操作のエラー
あれれ?
何度かやってるうちに上手くいったので、一旦サブフォームを
閉じて再度実行後、サブフォームをドラッグ(移動)したとたん
何と、サブフォームがタイトルバーだけ残って後は消滅。
???何だこれは。
その後エラーの雨嵐
初めてじゃこんな現症(;_;)

関数内でResultをそのまま使って集計させていたわけですが。
これが曲者だったのか、あれやこれや悩んだ末、取り敢えず
ローカル変数(arrData)を一個宣言して、これを使ってデータ
を集計して最後に Result := arrData;
たったこれだけで、うそのように現症が治まりました。
う〜む、こういったケースで関数内でResultはそのまま使っ
ちゃいけなかったけ?

だとしたら、私は今までいったい・・・。
他にも使っているけど今のところ問題ないのでやはり、どこか
に虫ちゃんが潜んでいるのかな(^_^;)

[500] Re:教えて Result返信 削除
2005/11/9 (水) 21:25:28 Mr.XRAY
▼ Syakeさん
 こんばんは

> を集計して最後に Result := arrData;
> たったこれだけで、うそのように現症が治まりました。
> う〜む、こういったケースで関数内でResultはそのまま使っ
> ちゃいけなかったけ?


そんなことはないと思うのですが.何かResultが変化しているのかな.
いや,私も使うことがありますが,関数内ではなるべく使わないようにして
います.一旦ローカル変数に入れて,最後にResultに代入するようにはして
います.その方が確実だと思いますけど.

  Result:=Result....
だとコードによっては,永久ループになるかも.

あと,Resultではないのですが,VCLをみても,他の方もあまりやっていない
方法として,条件判断にFlagなどというローカル変数をフラグにすることが
あります.昔みたいに,1バイトでも節約するアセンブラのコードだと無駄
でしょうけど.

[502] Re2:教えて Result返信 削除
2005/11/9 (水) 21:37:53 Syake
▼ Mr.XRAYさん

早速にありがとうございます。
 
> そんなことはないと思うのですが.何かResultが変化しているのかな.
もう一度よく見てみます。

> いや,私も使うことがありますが,関数内ではなるべく使わないようにして
> います.一旦ローカル変数に入れて,最後にResultに代入するようにはして
> います.その方が確実だと思いますけど.

なるほど、その方が安牌ですか。

>   Result:=Result....
> だとコードによっては,永久ループになるかも.
>
> あと,Resultではないのですが,VCLをみても,他の方もあまりやっていない
> 方法として,条件判断にFlagなどというローカル変数をフラグにすることが
> あります.昔みたいに,1バイトでも節約するアセンブラのコードだと無駄
> でしょうけど.


いろいろ、ありがとうございます。
参考にさせていただきます。


[503] Re3:これがいけないResult (見直し)返信 削除
2005/11/10 (木) 08:55:21 Syake
おはようございますマスター(こんばんはかな)

色々見直してみました。
今までで問題なかったパターンと、今回問題になったパターンを
比べてみました。

//問題なく処理されるパターン:
function XXXX(XX:XX):TDynamicArrRecordData;
var
 i:Integer;
begin
 ・・・(前処理)
 Result := nil;//必要ないけど書かないと気がすまない。
 ADODataSset1.CommandText := 'xxx';
 Try
  ADODataSet1.Open;
    if ADODataSet1.RecordCount > 0 then
    begin
       SetLength(Result,ADODataSet1.RecordCount);
       for i := 0 to ADODataSet1.RecordCount -1 do
       begin
     ・・・・
          Result[i].fYxxxx := ADODataSet.FieldByName('SSS').AsXxxxx;
          ・・・・
       end;
    end;
    ADODataSet1.Close;
  except
   ・・・(エラー処理)
  Result := nil;
 end;
end;
//Resultを条件には使う事はなかった。
//Resultに再度値を入れなおしはしていなかった。
これは、今まで問題は無かった。

//エラーを頻発した今回のパターン:
前述した処理で一旦Resultに値を入れた後
再度別のデータセットを開いて

  if Result <> nil then
  begin
  ・・・(別のデータセットを開く)
  ADODataSet1.Open;
    if ADODataSet1.RecordCount > 0 then
    begin
       for i := 0 to ADODataSet1.RecordCount -1 do
       begin
          for j := 0 to Length(Result) -1 do
          begin
           if Result[j].fXxxx = ADODataSet1.FieldByName('YYYY').AsXxxxx then
           begin
                Result[j].fYxxxx := ADODataSet1.FieldByName('ZZZZ').AsXxxxx;
           end;
          ・・・・
       end;
    end;
    ADODataSet1.Close;
  end;

//今までと異なったところ
//まあ結果的にResultを使いまくり、判断、参照、値の入れ替え
//何でもござれ状態でした。
これがいけなかったのかな。

マスターの言われるとおり、ローカル変数が安心ですね。

以上、見直した結果報告のゴミレスです。



[504] すいません、やっぱり虫ちゃんでした。返信 削除
2005/11/10 (木) 09:11:44 Syake
▼ Syakeさん

マスター、朝っぱらからすいません。
大変申し訳ございませんでした <m(__)m>

   if Result <> nil then
   begin
   ・・・(別のデータセットを開く)
   ADODataSet1.Open;
     if ADODataSet1.RecordCount > 0 then
     begin
        for i := 0 to ADODataSet1.RecordCount -1 do
        begin
           for j := 0 to Length(Result) -1 do
           begin
            if Result[j].fXxxx = ADODataSet1.FieldByName('YYYY').AsXxxxx then
            begin
              → Result[i].fYxxxx := ADODataSet1.FieldByName('ZZZZ').AsXxxxx;
            end;
           ・・・・
        end;
     end;
     ADODataSet1.Close;
   end;

こりゃ、エラーになります。
しかも、ローカル変数を宣言した際 //Length(Result)の箇所を
変更するのを忘れていたと言う、おお戯け者のでした。
あたかも、上手く言ったいったように見えるわけです。

二度、三度と初歩的なミスをやってしまいました。
なんと申し上げてよいやら、お恥ずかしい。
お騒がせしました。



[505] Re:すいません、やっぱり虫ちゃんでした。返信 削除
2005/11/10 (木) 19:47:14 Mr.XRAY
▼ Syakeさん

これはですね.よくあることです.私も.ハイ!!
しかも,本人は,「おかしいな,おかしいな〜」を頭の中で繰り返す.
「どこも間違っていないよなぁ〜」
それよりも,これこれ,

>Result := nil;//必要ないけど書かないと気がすまない。

これよくやりますね.初期化や,取敢えず暫定値.
で,「〜に代入された値は使用されていません」とか警告がでると
削除するとか.(^^ゞ



INCM/CMT
Cyclamen v3.82