- ベストアンサー
VBのコーディングについて
- VBの課題で行き詰ってしまったので、力を貸していただければと思います。
- 商品一覧からレコードを取得し、商品区分で集計し、商品区分・商品件数・売上合計金額を区分別売上表に出力する
- コーディングですと、欲しいデータが返ってこないので、どなたかご教授いただけないでしょうか?
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
はじめまして 集計等は、先に配列変数を作って、入れておき、後で計算するのがやりやすいかと・・・ 僕なりに書いてみました。ご参考になればと・・・ Private Sub コマンド1_Click() Dim INP_DATA As String Open "C:\INFILE.txt" For Input As #1 Open "C:\OUT_FILE.txt" For Output As #2 'いる分だけ配列変数を作る方法もあるが、とりあえず、多めに変数を作る Dim kubun(10) As String Dim syohin(10) As String Dim uriage(10) As Integer 'ループ用変数 Dim i As Integer Dim a As Integer '初期値セット i = 1 a = 0 Dim kubun_01 As String Dim syohin_01 As Integer Dim uriage_01 As Integer Dim kubun_02 As String Dim syohin_02 As Integer Dim uriage_02 As Integer 'ファイルの終了までループ Do Until EOF(1) Line Input #1, INP_DATA '読み込んだレコードの各項目を変数に代入 kubun(i) = Trim(Left(INP_DATA, 10)) syohin(i) = Trim(Mid(INP_DATA, 11, 10)) uriage(i) = Right(INP_DATA, 8) 配列変数確認用 Debug.Print kubun(i) Debug.Print syohin(i) Debug.Print uriage(i) '配列番号用 i = i + 1 Loop '何個、配列変数が出来たか、保存する a = i '一行目を変数にセット kubun_01 = kubun(1) syohin_01 = 1 uriage_01 = uriage(1) '2行目からは、ループしながら集計 For i = 2 To a - 1 If kubun_01 = kubun(i) Then syohin_01 = syohin_01 + 1 uriage_01 = uriage_01 + uriage(i) Else kubun_02 = kubun(i) syohin_02 = syohin_02 + 1 uriage_02 = uriage_02 + uriage(i) End If Next '変数確認用 Debug.Print kubun_01 Debug.Print syohin_01 Debug.Print uriage_01 Debug.Print kubun_02 Debug.Print syohin_02 Debug.Print uriage_02 '後は OUT_FILE.txt に、↑の変数を書き出せばいいのでは Debug.Print "PROGRAM END" Close #1 Close #2 End Sub 今は kubun が、2種類しか集計していませんが、IF等の分岐でそれぞれ集計を追加して下さい。 不備があったら、すいません。
その他の回答 (4)
- AKARI0418
- ベストアンサー率67% (112/166)
私ならばこんな感じで作ると思います。 SQLを使用することで、拡張性が格段にあがります。 Sub my_test() 'ADODBを利用するために参照設定ActiveX Data Objects 2.8 Libraryを追加してください。 '定数 Const InputFile As String = "C:\INFILE.txt" Const OutCSVDir As String = "C:\" Const OutCSVFileName As String = "OUTCSVFILE.txt" Const OutCSVFile As String = OutCSVDir & OutCSVFileName Const OutFile As String = "C:\OUTFILE.txt" Const Kubuns As String = "区分,商品名,売上" Dim inp_fileNum As Integer Dim out_csvfileNum As Integer Dim inp_data As String Dim kubun As String Dim syohin As String Dim uriage As Integer Dim write_data As String inp_fileNum = FreeFile 'CSVファイルを作成する Open InputFile For Input As #inp_fileNum out_csvfileNum = FreeFile Open OutCSVFile For Output As #out_csvfileNum write_data = Kubuns Print #out_csvfileNum, write_data 'ファイルの終了までループ Do Until EOF(inp_fileNum) Line Input #inp_fileNum, inp_data '読み込んだレコードの各項目を変数に代入 'kubun = Trim(Left(inp_data, 10)) '取り込んだときに、均等な幅にするためにトリミングしない kubun = Left(inp_data, 10) syohin = Trim(Mid(inp_data, 11, 10)) uriage = Right(inp_data, 8) write_data = kubun & "," & syohin & "," & uriage Print #out_csvfileNum, write_data Loop Close #out_csvfileNum Close #inp_fileNum Dim cn As ADODB.Connection Dim rs As ADODB.Recordset Dim strConnectionString As String Dim strSQL As String Dim out_fileNum As Integer Dim out_data As String Set cn = New ADODB.Connection Set rs = New ADODB.Recordset strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & OutCSVDir & ";" & _ "Extended Properties=""Text;HDR=YES;FMT=Delimited""" strSQL = "SELECT 区分,COUNT(区分), FORMAT(SUM(売上),'00000000') FROM " & OutCSVFileName & " GROUP BY 区分" cn.ConnectionString = strConnectionString cn.Open rs.Open strSQL, cn, adOpenStatic, adLockOptimistic, adCmdText out_fileNum = FreeFile Open OutFile For Output As #out_fileNum rs.MoveFirst While Not rs.EOF 'レコード数分ループ out_data = vbNullString For i = 0 To rs.Fields.Count - 1 out_data = out_data & rs.Fields(i).Value If i <> rs.Fields.Count - 1 Then 'スペース区切り out_data = out_data & " " End If Next i Print #out_fileNum, out_data '次のレコードへ rs.MoveNext DoEvents Wend Close #out_fileNum rs.Close cn.Close Set rs = Nothing Set cn = Nothing End Sub もとデータをCSV形式に展開し、CSVファイルへADODBを使用してアクセスすることで、SQLを実行しています。 しかも早いです。 読み込み件数が多い場合は、自力読み込みよりも早い場合が多いです。 中間ファイルのCSVファイルは邪魔ならばkillしてください。 参照設定を行いたくない場合は、遅延バインディングを行う用に変更してください。
お礼
SQLを使うとできるんですね。。 まだ、初心者の私にはちょっとレベルが高すぎるので、 もう少しVBを学んでからもう一度チャレンジしてみたいと思います。 何度も回答していただき、本当にありがとうございました。
- maido_desu
- ベストアンサー率50% (3/6)
>syohin_01をsyohin(1)としないのはなぜでしょうか? 集計結果は、区分別の商品数と合計金額が欲しいんですよね。 syohin(1)には、オレンジジュースなどの名前が入っていて、商品数とは関係ないので、使ってません。 syohin_01には、同じ区分がきたら + 1 しているだけです。 >と、飲料以下のグループが最後のグループである >調理器具に足されてしまいました。 >この場合どのようにすれば、各項目ごとの件数と売上合計が得られるでしょうか? 区分名(飲料や調理器具)は、何種類ありますか?
補足
>syohin_01をsyohin(1)としないのはなぜでしょうか? ↑わかりました。ありがとうございます。 区分は4つ作りましたが、何個あるかわからない前提で、 何個区分があったとしても対応できるコーディングにしたいと 考えています。 ↑というのは可能でしょうか??
- y_yyy
- ベストアンサー率12% (1/8)
OUT_FILEに書き出しているコードはどこにあるのでしょうか。。。
補足
そうですね、書き出しのコードを書いていませんでした。 また、長くなってしまって申し訳ありませんが、 あらためて作ってみたのが Private Sub コマンド1_Click() Dim INP_DATA As String Dim OUT_STRING As String Dim kubun_01 As String Dim syohin_01 As String Dim uriage_01 As Integer Dim kubun_02 As String Dim syohin_02 As String Dim uriage_02 As Integer Dim goukei As String 'ファイルを開く Open "C:INFILE.txt" For Input As #1 Open "C:OUTFILE.txt" For Output As #2 Do Until EOF(1) Line Input #1, INP_DATA '読み込んだレコードの各項目を変数に代入 kubun_01 = Trim(Left(INP_DATA, 10)) syohin_01 = Trim(Mid(INP_DATA, 11, 10)) uriage_01 = Right(INP_DATA, 8) 'さらに次の行を抽出し、比較する Line Input #1, OUT_STRING kubun_02 = Trim(Left(OUT_STRING, 10)) syohin_02 = Trim(Mid(OUT_STRING, 11, 10)) uriage_02 = Trim(Right(OUT_STRING, 8)) If kubun_01 = kubun_02 Then goukei = uriage_01 + uriage_02 Print #2, kubun_01; goukei End If '新たに比較用の変数に格納 kubun_01 = Trim(Left(INP_DATA, 10)) syohin_01 = Trim(Mid(INP_DATA, 11, 15)) uriage_01 = Right(INP_DATA, 8) Loop Debug.Print "PROGRAM END" Close #1 Close #2 End Sub と、打ち込んでみました。 INP_FILEには 飲料 オレンジジュース 00000300 飲料 紅茶 00000650 調味料 ケチャップ 00001200 調味料 マヨネーズ 00000900 調味料 しょうゆ 00001500 調味料 オリーブオイル 00002300 となっていて、 飲料 2 00000950 調味料 4 00005900 となってほしいのですが、実際には OUT_FILEには 飲料950 調味料2100 調味料3800 食品2450 調理器具9700 となってしまいました。 ・件数の出し方 ・重複しているグループのまとめかた(調味料が分かれてしまっているので) を教えていただけたらと思います。 よろしくお願いいたします。
- y_yyy
- ベストアンサー率12% (1/8)
ある程度デバッグはされましたでしょうか。 どういった意味で、「欲しいデータが返ってこない」のかが、 文章から読み取れません。 欲しいデータは、まずどのようなものか、例があるとわかりよいです。 また、上記のコードを実行した結果、どうなるから、予想と違うのかが あるとさらにわかりよいです。 実行時エラーがでてるのかどうか。 たとえば、INP_DATAにはどんな値で取得できていて、それが予想とどう違うのか。etcetc...
補足
ご指摘ありがとうございます。 INP_DATAには 飲料 オレンジジュース 00000300 飲料 紅茶 00000650 調味料 ケチャップ 00001200 調味料 マヨネーズ 00000900 調味料 しょうゆ 00001500 : : : のようなデータが入っています。 最終的には 飲料 2 00000950 調味料 3 00003600 : : : というような答えがOUT_FILEに表示されて欲しいのですが 上記のコーディングだと何も表示されないのです。
お礼
丁寧な解説とともにお答えいただきありがとうございます。 上記のコードを入力し、 >'一行目を変数にセット >kubun_01 = kubun(1) >syohin_01 = 1 >uriage_01 = uriage(1) とありますが、syohin_01をsyohin(1)としないのはなぜでしょうか? また、 Print #2, kubun_01; syohin_01; uriage_01 Print #2, kubun_02; syohin_02; uriage_02 を足して出力してみたのですが、結果が、 飲料2 950 調理器具 8 18050 と、飲料以下のグループが最後のグループである 調理器具に足されてしまいました。 この場合どのようにすれば、各項目ごとの件数と売上合計が得られるでしょうか? ifの分岐で、3つ以上の分岐はできるのでしょうか? お礼のはずが質問ばかりになってしまい申しわけありません。