フサギコの *やさしい* Delphi質問スレ Ver.12

このエントリーをはてなブックマークに追加
Delphi中毒(末期)の漏れが言うのもなんだけど、何事も適材適所。
セルの計算がしたいだけならExcelで組むのがいいとおもうよ。

新人さんにこそよくよく聞いて欲しいんだけど、どの設計方針で組むのが
一番コストがかからないのか、組み始める前にじっくり考える癖をつけて欲しい。

それでもDelphiにしたいならまた来てよ。そのときは歓迎するよ。
953デル:03/03/23 22:06
Excelは遅いからDelphiにするんですけど

Excelで1つのファイルのデータを貼り付けて計算して結果出すのに
30秒から1分かかります。4000ものファイルを計算させるととんでもない
ことになります。

最初に作ったのは1つのファイルのデータを4000のファイルに振り分けるものです
Excelでは40分から50分かかります。
delphiでは25秒でした。

Excelはファイルオープン、クローズに時間がかかります。
だからDelphiにするのですが、いけませんか?
>>953
だからと言ってプログラミング歴1週間ではいかんともしがたいぞ。
955デル:03/03/23 22:53
そうですね。
一応サンプル探してCSVのデータの4列めと5列めをたして、6列めに
書くコードを作って見ましたが、エラーが出ます

procedure TForm1.Button1Click(Sender: TObject);
var
d: array[0..14] of string;
o: array[0..14] of string;
h: array[0..14] of string;
l: array[0..14] of string;
c: array[0..14] of string;
k: Integer;
StringList1:TStringList;
string_a_line:WideString;
// 2バイト文字を正確に扱うために、WideString とした
i,j:Integer;
begin
// テキストファイルからデータを読み取る作業
StringList1:=TStringList.Create;
try
StringList1.LoadFromFile('C:\test\test.csv');
for i:=1 to StringList1.Count-1 do
begin
string_a_line:=StringList1.Strings[i];
// 1行分を取り出します。
j:=Pos(',',string_a_line);
// カンマの位置を見つけ
d[i]:=Copy(string_a_line,1,j-1);
// カンマの前までの文字列を読み込み、配列に代入
string_a_line:=Copy(string_a_line,j+1,length(string_a_line));
// 最初のカンマの次の文字以降を新たな string_a_line とする
// 以下は同等の処理の繰り返し
956デル:03/03/23 22:54
j:=Pos(',',string_a_line);
o[i]:=Copy(string_a_line,1,j-1);
string_a_line:=Copy(string_a_line,j+1,length(string_a_line));
j:=Pos(',',string_a_line);
h[i]:=Copy(string_a_line,1,j-1);
string_a_line:=Copy(string_a_line,j+1,length(string_a_line));
j:=Pos(',',string_a_line);
l[i]:=string_a_line;
string_a_line:=Copy(string_a_line,j+1,length(string_a_line));
c[i]:=string_a_line;
if i=14 then // 配列変数のすべてにデータが入ったら
break;
end;
finally
StringList1.Free;
end;
try
for i :=1 to StringList1.Count-1 do
begin
k:=StrToInt(l[i])+StrToInt(c[i]);
StringList1.Strings[i]:=StringList1.Strings[i]+','+IntToStr(k);
end;
StringList1.SaveToFile('C:\test\test.csv');
finally
StringList1.Free;
end;
ShowMessage('終了しました');
end;
end.
どのようなエラーが出たのかを書けないと意味ないね
958デフォルトの名無しさん:03/03/24 00:21
Imageコンポーネントにあるpictureを消す場合って、単純に
> Image.picture := nil
で良いのでしょうか?

試しに、Image1.picture:=nil;
if (Image1.picture=nil) then showmessage('ほげ'); ってやってみても何も出てこなかったのが
非常に気になっているのですが・・・。
>>958
きっとメモリリーク起こしてます。
Image1.picture=nil ←これいくない。
Not Assigned(Image1.picture)←こちらを奨める

理由はヘルプ嫁
try‥finallyの使い方間違ってますし、
数値に変換するのに2バイト文字というのは意味不明。
CommaTextでも使え。
クラスAとクラスBがあって、
クラスAのメンバにクラスBのオブジェクトを宣言して
クラスBのメンバにクラスAのオブジェクトを宣言するにはどうしたらいいのでしょうか?

A = class
private
    bbb:    B;
end;

B = class
private
    aaa:    A;
end;

こんな感じですがクラスAを宣言する時にクラスBが定義されていないので
エラーになってしまうのですが、どうすればよいのでしょうか?
Aを宣言する前に
B = class;
とforward宣言しておく。
>>958
.visible := False;
>>964
ありがとうございました
また1つ勉強になりました。
967デル:03/03/24 06:34
>>957

デバッガ例外が発生
EAccessViolationクラスの例外を生成しました。
アドレス00000000でアドレス00000000に対する読み込み違反がおきました。

です
つーか1週間やっただけでExcel越えようと思うのは妄想が激しすぎると思ふ。
>>968
なんでもやり始めというのは壮大な夢を持つものさ。特にプログラミングは。
プロと同じツールを使うわけだからね。

だからと言って、他人を巻き込むなと言いたいわけで。
970デフォルトの名無しさん:03/03/24 09:13
むか〜しD3Professionalを使って、Paradoxのデータベースのアプリをかじった
のですが、再び始めようと思ってます。

無償配布のD6PersonalはD3proのDataAccessやDataControlsのような機能が
ないようなんですが、やっぱり有料版を使わないと駄目なんでしょうか。
Borlandのサイトではデータベース機能を利用するにはProfessionalでないと
駄目みたいなことが書いてあるんですが、他にやり方とかあるんでしょうか。
>>959-960
ありがとうございます。ポインタが無効な場合が・・・なるほど。

procedure TForm1.FormCreate(Sender: TObject);
begin
 Image1.picture.LoadFromFile('test.bmp');
  if assigned(Image1.picture) then showmessage('hoge1');
 Image1.picture:=nil;
  if assigned(Image1.picture) then showmessage('hoge2');
end;

で、試しにFormにImageをひとつだけ置いてこうやってみたんですが、
何故か、両方のダイアログが出現・・・Form上ではpictureは消えてるんですが・・・。(ノД`)?
972デフォルトの名無しさん:03/03/24 12:31
バイナリファイルにテキストデータを付け加えたいのですが

AssignFile(f, 'test.txt');
Append(f);
Write(f, textdata);

で行なうと、以前書き込んだバイナリデータの上に上書きしてしまいます。
つまり、appendを使ってもファイル末尾に書き込んでくれないのですが
どうすればいいのでしょうか?
ヘルプを読むと、末尾128バイト以内に云々と書いてありますが・・
973デル:03/03/24 12:36
>>969

>だからと言って、他人を巻き込むなと言いたいわけで。
じゃあでてくるなよ

最初は誰でも素人
デルファイが伸びないのは、あなたのような人がいるからかもしれないね

>>971
Picture.FreeとしないとAssignedではFALSEにならんよ

Image1.Picture.Graphic.Assign(nil);
if Image1.Picture.Graphic.Empty then
としてみてはどう?
>>972
Append は ctrl+Z の後に追加するのでそうなります。

TFileStream を使って、書き込みポインタを最後にもってきてから書くといい
>>975
はい、チャレンジしてみます。ありがとうございました。
977デフォルトの名無しさん:03/03/24 13:30
>>975
・・ってバイナリデータの書き込みの際にTFileStreamは使っているので
それをそのまま使ってみます。

WriteBufferでバイナリデータは書いていますが、
テキストデータの場合、どうすれば書き込めますか?
var
TextData: string;
FileStream: TFileStream;
である場合、どうなるのですか?

FileStream.WriteBuffer(TextData, length(TextData));

ではうまき行きませんでした。

>977
FileStream.WriteBuffer(TextData[1], Length(TextData));
次スレどこ〜?
>>978
そんなことだったのですかぁ・・・・あああ
全然理解していなかった私・・・
どうもありがとうございました。m(__)m
>>963-964
後方参照できないところがC言語にちょっとだけ似ていないこともない。
>>981
PascalとCはいとこみたいなもの(Pascalの方がちょっと年上)
983デフォルトの名無しさん:03/03/24 21:48
TActionListって何のために使うんですか?
>>983
メインメニュー、ポップアップメニュー、ボタン
などで共通の動作をさせるときに一元管理できるようにしたもの
(分類して管理できる)

だけどメニューのキャプションとボタンのキャプションは同一ではないので
結局思ったほど便利じゃなかった罠
985デフォルトの名無しさん:03/03/24 22:52
ActionList使ってみたけど、あんまし使いかってよくなかったな。
へんてこなコンポいらんから新しいhファイルの変換して素早く公開するくらいのことしてほしい。
Action/ActionListのメリットが理解できない奴は抽象的な思考に不自由な奴が多い。
TStreamクラスとその派生クラスのWriteメソッドとWriteBufferメソッドはどう違うの?
何か使い分けとかあるの?
>>987
Writeメソッドは抽象オブジェクトなので、
派生オブジェクト上でWriteを使って必ず同じ動作をするとは限らない。
素直にWriteBuffer使っておけ。
ウンコンポは要らない!
>>989をラッピングしてみたんですが・・・いらないですね。
991デフォルトの名無しさん:03/03/25 12:13
DelphiのIDEのように
上のMenuを隠さないような最大化を
実現するにはどうするのでしょう?

大きさはTSizeConstraintsで制御出るようですが
X,Y座標の設定をどうするのか悩んでいます

よろしくお願いします。
>>991
ウインドウメッセージ取るとか、タスクバー領域に指定しちゃうとか。
993デフォルトの名無しさん:03/03/25 13:12
>>992
すみません。
私の技量が足りなくて、言葉だけの説明だけでは
理解できません・・・

現在、上にメニュー。下にワークフォームを用意しています
タスクバー領域に指定とは
上のメニューをOSにタスクバーと認識させると言った解釈で
よろしいのでしょうか?
994デフォルトの名無しさん:03/03/25 13:14
ステップ実行し、変数ウォッチすればわかる。
WM_GETMINMAXINFO メッセージを処理するメソッドを定義して、
ウィンドウの位置を調整する。
D6 以降なら、{Public 宣言} の真下あたりで Ctrl-Space 押して wmgetmin って打つと
"procedure WM_GETMINMAXINFO...." ってのが出てくる。これをリターンで確定すると
WMGetMinMaxInfo メソッドが定義されるから、Shift-Ctrl-C でクラス定義を補完。

実装部分に、たとえば
 Message.MinMaxInfo.ptMaxSize := 600;
って打つと、最大化ボタンを押しても幅 600 どっとになる。
996デフォルトの名無しさん:03/03/25 14:54
>>995
これもわかりやすい説明をしてくれるなんて
涙が出そうです(質問してよかった・・・)
ありがとうございます!!

早速やってみると
MainFormの指定(下記のソースでY座標に当たる部分)では
うまくいきました

しかしその後オブジェクトインスペクタの様なメニューも欲しかったので
左に新しいFormを作成することにしました。
しばらくの作業後、Formもできました(ToolForm)。
WorkFormの最大化制御コードを拡張しようと
教えて頂いた事を元に以下のように書きました

procedure TfrmSDIWork.WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo);
var
 MaxPoint :TPoint;
begin
 //ToolFormのレフトと幅を加えたものをX座標に
 MaxPoint.X := frmSDITool.Left + frmSDITool.Width; //Err...
 //MenuFormのトップと高さを加えたものをY座標に
 MaxPoint.Y := frmSDIMenu.Top + frmSDIMenu.Height; //OK!!
 Message.MinMaxInfo.ptMaxPosition := MaxPoint;
end;
997デフォルトの名無しさん:03/03/25 14:55
続き

このソースでは
MaxPoint.Y := frmSDIMenu.Top + frmSDIMenu.Height;の部分では
うまくいくものの
X座標指定の
MaxPoint.X := frmSDITool.Left + frmSDITool.Width; //Err...
でエラーが出ます

どうやらToolForm = nilの様なのですが(Assignedで調べました)
このWorkFormを作成するときには既にToolFormは存在しています

何か見落としている点がありませすでしょうか?
998987:03/03/25 15:45
>> 988
サンクスです。
999991:03/03/25 15:50
自己解決しました

どうやら原因はfrmSDIToolLeftの変数を使って
インスタンスを作成していませんでした

お騒がせしてすみませんでした
1000!
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。