Visual Basic6.0を使ったプロファイル補正についてPart2

このQ&Aのポイント
  • Visual Basic6.0を使用してプロファイル補正を行う方法について解説します。
  • プロファイル補正には、定数や配列を使用して値の処理を行います。
  • プロファイル補正の結果をテキストファイルに出力することも可能です。
回答を見る
  • ベストアンサー

Visual Basic6.0を使ったプロファイル補正についてPart2

Private Sub Command1_Click() step = 0.25 ←式の定数 ramda = 0.5 ←式の定数 Dim Data(0 To 399) ←400個値を持つ配列を定義 Open "C:\hosei1.txt" For Input As #1 ←開くファイルの指定 Data(399) = Input(400, #1) ←読み込んだ値を配列に指定(型が違うとエラーがでます)                      surface = 1 ←surfaceを初め1にする l = 400 ←値の数 Do While surface < l g = 0 h = 0 i = surface Do While i < l ←1未満まで繰り返し h = h + (Data(i + 1) * Exp(-((i - surface + 1) * step) / ramda) + g) * step / 2 g = Data(i + 1) * Exp(-((i - surface + 1) * step) / ramda) z = CSng(h / ramda * (1 - Exp(-(step * (l - surface) / ramda)))) i = i + 1 Loop Print (CSng(z)) ←計算値を出力 surface = surface + 1 Loop Listing1 = Array(List1, l) > output.txt ←計算値をテキストに出力 End Sub ←終了 以上です。お願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • itohh
  • ベストアンサー率45% (210/459)
回答No.4

こんにちは。itohhといいます とりあえず、動くようになって良かったですね。 >このあとグラフ作成するので一列に表示されてほしい これって、縦一列ですよね? 横一列だと400個の数値を表示するのはムリがありますものね(^^; テキストボックス(Text1)のスクロールバーの表示は、 テキストボックス(Text1)のプロパティを変更します。 ScrollBars プロパティ:両方(縦だけでよいのでしたら「垂直」) MultiLine プロパティ:True これだけでOKです。 >MSDNに大量の情報が書かれているので思うように知りたいことを調べることができません。 >何か良い方法があるのでしょうか? ヘルプの使い方には、いろいろな方法があります。 1.ソースコードの調べたい単語にカーソルを持っていって、   左上にある[F1]キーを押下する。 2.プロパティウィンドウの調べたいプロパティにカーソルを持っていって、   左上にある[F1]キーを押下する。 3.VBのメニュー「ヘルプ」の中の「キーワード」または「検索」で調べたい単語を入力する。 ※これで、MSDNライブラリーの該当項目を表示してくれます。 この後、「使用例」をクリックすると、サンプルコードが表示されます。

seikoinst
質問者

お礼

MultiLineだったんですね(^。^)。Falseになっていました。だからスクロールバーが表示されなかったんですね。それとファンクションキーは結構役に立つんですね。どうも有難うございました。分かりやすい説明大変感謝いたします。 今回のプログラムでVBは面白いなーって実感しました。これからいろいろ勉強したいと思います。

その他の回答 (3)

  • itohh
  • ベストアンサー率45% (210/459)
回答No.3

こんにちは。itohhといいます。 ファイルへの出力ですが、まずヒントだけ。 1.outputでファイルをオープンしましょう。 > Print CSng(z) 2.上記のPrint文では、どのファイルに出力したらよいかわかりません。   Inputのとき#1としたようにどのOpen文と関係するのかを明記しなければいけません。   (ファイル番号といいます) 3.出力がすべて終わったらClose文でファイルを閉じてください。 ※Input文のほうもCloseしましょう。 ※使用している変数は関数の最初にDim文で定義するようにしてください。 そして、必ずデータ型を指定するようにします。 そうすれば、CSng(z)などの変換が必要なくなるはずです。 まず、ヘルプを良く理解することです。ヘルプには、もっと細かいサンプルが載っていますよ。 あと、フォーム上に表示したいとのことですが、どのようにコードを書いたのでしょうか? できれば、そのコードを記載してください。 >スクロールバーの使い方もよく分かりません どういうときのスクロールバーでしょうか? > If (RecCnt > 401) Then 400までしかないので401ではなく400にしましょう。

seikoinst
質問者

補足

Private Sub Command1_Click() step = 0.25 ramda = 0.5 Open "C:\hosei1.txt" For Input As #1 Dim RecCnt As Integer Dim Data(1 To 400) RecCnt = 1 Do While Not EOF(1) If (RecCnt > 400) Then Exit Do End If Input #1, Data(RecCnt) RecCnt = RecCnt + 1 Loop Close #1 Open "C:\hosei2.txt" For Output As #2 surface = 1 l = 400 Do While surface < l g = 0 h = 0 i = surface Do While i < l h = h + (Data(i + 1) * Exp(-((i - surface + 1) * step) / ramda) + g) * step / 2 g = Data(i + 1) * Exp(-((i - surface + 1) * step) / ramda) z = CSng(h / ramda * (1 - Exp(-(step * (l - surface) / ramda)))) i = i + 1 Loop Print #2, CSng(z) surface = surface + 1 Loop Close #2 End Sub このようなプログラムで補正計算を無事することができました(^o^)。 どうも有難うございました。 >フォーム上に表示したいとのことですが、どのようにコードを書いたのでしょうか? できれば、そのコードを記載してください 計算過程をテキストボックスに出したかったのでフォーム上にText1をつくり、      Text1.Text=Text1.Text & CSng(z) & vbCrLf というコード(これは私が持っているVBの参考書の例題にありました)を書いたのですが、実行後、Text1には横に続けて値が表示されて最初の値しか分からない(ドラッグして動かせば全ての値はみれますが)といったようになってしまいうまくいきませんでした(このあとグラフ作成するので一列に表示されてほしい)。   また、このText1にスクロールバーを付けて全ての値をスクロールにより見れるようにしたかった(計算の終了が分かると同時にコピーできる。)のですが、参考書にも説明が書かれておらず分かりませんでした。参考書の例題には、例題の実行結果の絵がフォーム上にスクロールバー付きのテキストボックスで表示されています(vbCrLfの説明もありません)。   どうすればテキストボックスにスクロールバー付きで表示できるのでしょうか? また、MSDNに大量の情報が書かれているので思うように知りたいことを調べることができません。何か良い方法があるのでしょうか? いろいろ教えて頂いて申し訳ないのですが、よろしくお願いします。

  • nakashi
  • ベストアンサー率51% (21/41)
回答No.2

Textファイル一行に1データと仮定して Dim sBuf As String Dim hFile As Integer Dim dData() As Double Dim iNumbOfData As Integer Dim iCalcPtr As Integer hFile = FreeFile Open "c:\temp\hoge.txt" For Input As hFile Do  If EOF(hFile) <> False Then Exit Do  Line Input #hFile, sBuf  ReDim Preserve dData(iNumbOfData)  dData(iNumbOfData) = Val(sBuf)  iNumbOfData = iNumbOfData + 1 Loop For iCalcPtr = 0 To UBound(dData)  Debug.Print dData(iCalcPtr) Next iCalcPtr

  • itohh
  • ベストアンサー率45% (210/459)
回答No.1

こんにちは。itohhといいます。 VBのヘルプ(MSDNライブラリー)は確認されました? とりあえず、こちらに回答します。 1.まずは、ファイルの読み込みについて > Data(399) = Input(400, #1) ファイルの入力のInput文では一気に全レコードを読み込めません。 レコード数分、繰り返し読み込みましょう。 (MSDNライブラリーのInputの説明にサンプルが載っていますよ) とりあえず、コードのサンプルを記載しますね。 Dim RecCnt As Integer RecCnt = 0 ' ファイルの終端までループを繰り返します。 Do While Not EOF(1) If(RecCnt > 399) Then ' 配列より大きくなったらループを抜ける ' (配列よりも多く設定しようとするとエラーになります) ' 必要ならエラー処理を書いてください Exit Do End If Input #1, Data(RecCnt) ' 配列n番目に読み込む RecCnt = RecCnt + 1 Loop 2.計算のループについて > Do While surface < l これって、以下のループのほうがシンプルではないでしょうか? For surface = 0 To l For i = surface To l ' 計算処理 Next i Next surface For文の使用方法の詳細はMSDNライブラリーで確認してください。 3.ファイルへの書き出し処理 読み込みと同じです、まず、ファイルをオープンしてからPrint文で出力します。 これも、MSDNライブラリーのPrintの説明にサンプルが載っていますよ! あえて、サンプルは書きません、ご自分で調べてみてください。

seikoinst
質問者

補足

どうも有難うございました。 無事走らせることはできたのですが、フォーム上にオブジェクトを作って、出力の値をテキストボックスに表示したいと思うのですが、うまく表示されません(スクロールバーの使い方もよく分かりません)。また、テキストファイルに出力する場合、ファイルをオープンしてからPrint文で出力する方法がうまくいきません(入力と同様にファイルを開いてそのファイルに書きこむとエラーがでる)。ヘルプを見てもテキストファイルにどうやって出力したらよいか分かりません。どうか出力方法を教えてください。 よろしくお願いします。 以下のプログラムでは出力がフォームに表示され値が重なり読み取ることができません。 Private Sub Command1_Click() step = 0.25 ramda = 0.5 Open "C:\hosei1.txt" For Input As #1 Dim RecCnt As Integer Dim Data(1 To 400) RecCnt = 1 Do While Not EOF(1) If (RecCnt > 401) Then Exit Do End If Input #1, Data(RecCnt) RecCnt = RecCnt + 1 Loop surface = 1 l = 400 Do While surface < l g = 0 h = 0 i = surface Do While i < l h = h + (Data(i + 1) * Exp(-((i - surface + 1) * step) / ramda) + g) * step / 2 g = Data(i + 1) * Exp(-((i - surface + 1) * step) / ramda) z = CSng(h / ramda * (1 - Exp(-(step * (l - surface) / ramda)))) i = i + 1 Print CSng(z) Loop surface = surface + 1 Loop End Sub

関連するQ&A

  • Visual Basic6.0を使ったプロファイル補正についてPart1

    私はプログラムが苦手なのですが、測定した濃度プロファイルをプログラムにより補正する必要性にかられています。Part2にプログラムを示しました。しかし、これではうまく走りません(プログラム初心者(ただいま勉強中です。)) 私がしたいのはテキストファイルから数値列(一列400行程度で値は2.1523e+19など)を読み込み、 h = h + (Data(i + 1) * Exp(-((i - surface + 1) * step) / ramda) + g) * step / 2 g = Data(i + 1) * Exp(-((i - surface + 1) * step) / ramda) z = CSng(h / ramda * (1 - Exp(-(step * (l - surface) / ramda)))) という式をつかって計算し、その計算結果をテキストで出力することです。 いろいろ本を見て調べているのですが、なかなかうまくいきません。 まず分からないのがテキストファイルから数値を入力しそれを配列にして計算するってことがよく分かりません。そして、計算された出力値を出力する関数が分かりません。いろいろ試しているのですが、うまくいきません。 プログラムに詳しい方、どなたか以下のプログラムの間違ってるところを指摘し、訂正して頂けませんか?よろしくお願いします。 また、デバックの使い方がよく分かりません。教えていただけませんか。

  • 高校数学の計算(指数)

    f{(1+exp(-πi(K+L))+exp(-πi(H+L))+exp(-πi(H+K))}=0 f:定数 π:円周率 H,K,L:いづれも整数 i:虚数 expX=e^X 上の式を満たすH,K,Lの条件はH,K,Lが偶数奇数混合の場合ということらしいのですが、なぜそうなるのか分かりません。 分かる方お願いします><

  • ダイヤモンドの構造因子

    ダイヤモンドの構造因子を求めると f{1+exp(-πi(h+k))+exp(-πi(k+l))+exp(-πi(l+h))+exp((-πi/2)(h+k+l))+exp((-πi/2)(3h+3k+l))+exp((-πi/2)(3h+k+3l))+exp((-πi/2)(h+3k+3l))} となったのですが、この構造因子が0になる指数がうまく求められません。どのように考えればよいでしょうか。

  • 構造体配列ポインタを引数で使うには

    いつもお世話になってます。 C言語を使って、構造体配列を引数として使って、サブ関数で取得した値(配列)をメイン関数に渡したいと思っているのですが、受け渡しが上手くできません。 現在以下の様に組んでいます。 /* 構造体宣言 */ typedef struct EXP1 { char sTime[17]; /* 開始日時 */ struct { int num; /* データ数 */ float data[96]; /* データ */ } getdata[5]; } EXP1 ; /* メイン関数 */ int func1( EXP1 ex1; for( loop = 0 ; loop < 5 ; loop++){ ans = funcGet( array1, &ex1.getdata[loop].data ); } if( ans = 0 ){ for( loop = 0 ; ; loop++){ printf("%f",ex1.data[count].pvdata[loop] ); } } } /* サブ関数 */ static int funcGet(int array, float *fvalue) { ans = calcvalu( array, fvalue ); //←float型で値が取得される。 for( i = 0 ; i < 10 ; i++ ) { printf("%f", *(fvalue + i); } return 0; } サブ関数で"fvalue"を確認したところ、正常に値が取得できているのですが、メイン関数では取得できていません。 どうかアドバイスをよろしくお願いします。

  • 結晶構造因子

    塩化ナトリウムの結晶構造因子は [Fna + Fcl・exp{-Πi(h+k+l)}][1+exp{-Πi(k+l)}+exp{-Πi(h+l)}+exp{-Πi(h+k)}] になります。 Fna,Fclはそれぞれナトリウムと塩素の原子散乱因子です。 この式のexp{-Πi(h+k+l)は何を意味するのでしょうか? 教えてください。

  • 読み込んだデータを配列へ代入する方法

    ---ここから--- 1,2 3,4 ---ここまで--- このようなファイルを読み込んでデータを配列へ格納するには, $pathname="D://data.txt"; open MYFILE, "$pathname"; @list=<MYFILE>; for($i=0;$i<2;$i++){ @dat=split(/,/,$list[$i]); print @dat; } close MYFILE; といったようなforあるいはwhileで1つの配列(上の場合だと@dat)に1行のデータを繰り返し入れていく方法しか思い浮かびません。できれば1行目のデータは@dat1という配列へ,2行目のデータは@dat2という配列へ,といったように行ごとに別々の配列へ代入させたいのですが良い方法はないでしょうか。 もしくは@dat=([1,2],[3,4])のような2次配列の形にでもできれば最高なのですが、、、

    • ベストアンサー
    • Perl
  • 限定的すぎてすみません

    数学の計算で答えはわかってるのですが その解法がわからないので質問させてください ∫[α^2/(α^2+p^2)]*exp[i*p*x/h]dp =(π*α)*exp[-α*x/h] (定数はα、h) お願いします

  • CSVファイルを読み込み、ファイル名を変更。

    CSVファイルを読み込み、ファイル名を変更。 使用言語はperlです。perlは初心者です。 アルゴリズムが、 CSVファイルを読み込み→2次元配列に格納→ファイル名変更 という流れになっているプログラムを作成中です。 CSVファイルの中身は あ.txt , a.txt い.txt , b.txt う.txt , c.txt です。 CSVファイルを読み込み2次元配列に格納するプログラムは以下のようにしました。 ----------------------------------- $i= 0; open IN, "sample.csv"; while (<IN>) { my @data = (); @data = split (/,/); for (0..@data) {$jdata[$i][$_] = "$data[$_]";} $i++; } close IN; ---------------------------------------- 「あ.txt」を「a.txt」に変更しようとして、この中に rename $jdata[0][0] , $jdata[0][1] ; と書いてみましたが、変換されません。 どう書けばよいのでしょうか。よろしくお願いします。

    • ベストアンサー
    • Perl
  • 2つのvoid関数でmallocを使うと2step目でセグメントエラーが出る

    プログラムのmainを見やすくするためにサブルーチンとしてvoid関数を使っているのですが、その中でmallocでメモリを確保して配列を作ろうとするとエラーが出てしまいます。概略を書くと #include <stdio.h> #include <math.h> #include <stdlib.h> //voidの宣言 void a(double* ,double*, double,); void b(double* ,double*, double,); main(){ double *c,*d,e; double *f,*g,h; c=(double *)malloc(sizeof(double)*N) //Nは適当な整数です d,f,gも同様の処理 色々な作業 while(適当回数繰り返します){ a(c,d,e); b(f,g,h); 色々な作業 } } void a (double* c, double* d, double e){ double **i,*j,; int k; i=(double **)malloc(sizeof(double *)*M) //Mは適当な整数です for(k=0;k<=M;k++){ i[k]=(double *)malloc(sizeof(double)*M) //Mは適当な整数です } jも同様にメモリ確保 様々な作業(逆行列の計算など) } void bはaとほとんど同じです。 mallocで二次元配列や配列を作っています。勿論同じ文字は使っていません。 以上のようなプログラムでgccは通ります。でも実行するとwhile内での1step目は上手くいくのですが、2step目のb内での始めの(double *)malloc(sizeof(double)*L)(Lは適当な整数です)で、つまりメモリ確保でセグメントエラーが出ます。両者とも片方を削るとエラーは出ません。1step目は何故上手くいくのか、2ステップ目で何故ダメなのかが分かりません。皆様の御教授をお願いします。

  • シリアル通信波形のなまり

    2つのマイコン間のシリアルデータラインを測定すると、"H","L"を繰り返している時は正常に矩形波になっているのですが、"H","L"が一旦止まった直後に垂直に"L"に落ちるところが、時定数を持っているかのように、ゆっくり"L"に落ちる波形になっていました。 マイコン間には対GNDにコンデンサがいるわけでもなく、ダンピング抵抗がシリーズにいるだけで、原因がわからないのですが、考えられることは何があるのでしょうか? 見にくいですが、下記のような波形です。    __ ___ ____   | | | | | \ __| |___| |___|   \____ なまって"L"へ落ち切る前に、次の通信が始まると下記のように途中でまた"H"になります。    __ ___ ____ ____ ____   | | | | | \ | | | | | | | | |   \ | | | | | | | | |   \| | | | __| |___| |___|   |___| |__ CMOSなので、Hi-Zになり浮遊容量などとでなまってるのでしょうか? シリアルはクロック、データI/O、CEの四本です。