[[20230303165537]] 『CSV取り込みとデータの処理をマクロだけでしたい』(マクロ勉強中) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『CSV取り込みとデータの処理をマクロだけでしたい』(マクロ勉強中)

CSVファイルを取り込んで「sheet(2)」タブに転記して
このデータをもとに「sheet(4)」に4点以上と3点以下のコメントを関数で
書き出しています。(コメントが空白のものは除く)

今のままだと関数のせいなのかマクロを起動したときに時間がかかりすぎるので、転記とコメントの書き出し全部マクロでしたいです。
一括処理できる方法を教えていただきたいです。

[CSVファイル]
A列 : B列 :C列: D列  : E列 :F列
1200:支払い: 3 :改善して:12/23:2313
2300:品揃え: 4 :    :12/24:4234
4500:対応 : 5 :良かった:12/28:5837


[sheet(4)]
  A列   : B列 
4点以上:3点以下
良かった :改善して

Sub レビューインポート()

    Dim TypeFile, DialogTitle As String
    Dim OpenFilepath As Variant
    Dim i As Long, j As Long
    Dim File_name As String
    Dim tmp As Variant

    TypeFile = "CSV ファイル (*.csv),*.csv"
    DialogTitle = "ファイルを選択して下さい"
    OpenFilepath = Application.GetOpenFilename(TypeFile, ,DialogTitle)

    j = ThisWorkbook.Sheets(2).Range("A" & Rows.Count).End(xlUp).Offset(1).Row
    If OpenFilepath = "False" Then Exit Sub

    Open OpenFilepath For Input As #1
    Line Input #1, buf
        Do Until EOF(1)
            Line Input #1, buf
            tmp = Split(buf, ",")
            j = j + 1
            For i = 0 To UBound(tmp)
                Cells(j - 1, i + 1) = tmp(i)
            Next
        Loop
    Close #1

End Sub

< 使用 Excel:Excel2016、使用 OS:Windows10 >


 配列にまとめて一括書き出しなら遅くならんと思う。
    Sub レビューインポート()
        Dim TypeFile, DialogTitle As String
        Dim OpenFilepath As Variant
        Dim i As Long, j As Long
        Dim File_name As String
        Dim buf As String
        Dim tmp As Variant
        Dim ans As Variant, cnt As Long
        TypeFile = "CSV ファイル (*.csv),*.csv"
        DialogTitle = "ファイルを選択して下さい"
        OpenFilepath = Application.GetOpenFilename(TypeFile, , DialogTitle)
        If OpenFilepath = "False" Then Exit Sub

        '配列の添え字
        cnt = 0
        '配列準備 [F1]はF列の列数(6)
        ReDim ans(1 To [F1].Column, 1 To 1)

        Open OpenFilepath For Input As #1
        Line Input #1, buf
            Do Until EOF(1)
                Line Input #1, buf
                cnt = cnt + 1
                tmp = Split(buf, ",")
                ReDim ans(1 To UBound(ans, 1), 1 To cnt)
                For i = 0 To UBound(tmp)
                    ans(i, cnt) = tmp(i)
                Next
            Loop
        Close #1

        '配列の行列を入れ替える
        ans = Application.Transpose(ans)
        '出力
        j = ThisWorkbook.Sheets(2).Range("A" & Rows.Count).End(xlUp).Offset(1).Row
        Cells(j, 1).Resize(cnt, UBound(ans, 2)).Value = ans
    End Sub
(稲葉) 2023/03/03(金) 17:38:22

 また間違えてた・・・
 Do-Loopの中のRedimにPreserveつけ忘れたので、変更お願いいたします。

 誤:ReDim ans(1 To UBound(ans, 1), 1 To cnt)
 正:ReDim Preserve ans(1 To UBound(ans, 1), 1 To cnt)

(稲葉) 2023/03/03(金) 18:09:06


Cells(j, 1).Resize(cnt, UBound(ans, 1)).Value = ans
の部分で「アプリケーション定義またはオブジェクト定義のエラー」とでてしまうのですが、
どうしたらいいですか。
cnt=0になっているので+1や+jで試しましたがエラーは出ないものの転記はされなかったです。
Cells(j, 1).Resize(cnt, UBound(ans, 1)).Value = ans
(マクロ勉強中) 2023/03/06(月) 12:04:36

 いくつか間違いあったので、こちらで再度試してみてください
 今度はテストしたので、大丈夫です

    Sub レビューインポート()
        Dim TypeFile, DialogTitle As String
        Dim OpenFilepath As Variant
        Dim i As Long, j As Long
        Dim File_name As String
        Dim buf As String
        Dim tmp As Variant
        Dim ans As Variant, cnt As Long
        Dim f As Integer '★
        TypeFile = "CSV ファイル (*.csv),*.csv"
        DialogTitle = "ファイルを選択して下さい"
        OpenFilepath = Application.GetOpenFilename(TypeFile, , DialogTitle)
        If OpenFilepath = "False" Then Exit Sub
        '配列の添え字
        cnt = 0
        '配列準備 [F1]はF列の列数(6)
        ReDim ans(1 To [F1].Column, 1 To 1)
        Stop 'ここからF5でステップ実行してください.
        f = FreeFile
        Open OpenFilepath For Input As #f
        'Line Input #f, buf ★消し忘れ
            Do Until EOF(f)
                Line Input #f, buf
                cnt = cnt + 1
                tmp = Split(buf, ",")
                ReDim Preserve ans(1 To UBound(ans, 1), 1 To cnt) '★
                For i = 0 To UBound(tmp)
                    ans(i + 1, cnt) = tmp(i) '★添え字の間違い
                Next
            Loop
        Close #f
        '出力
        If cnt > 0 Then '★
            '配列の行列を入れ替える
            ans = Application.Transpose(ans)
            With ThisWorkbook.Sheets(2) '★
                j = .Range("A" & Rows.Count).End(xlUp).Offset(1).Row '★
                .Cells(j, 1).Resize(cnt, UBound(ans, 2)).Value = ans '★
            End With
            MsgBox "出力しました"
        Else
            MsgBox "ファイルにデータがありませんでした"
        End If
    End Sub
(稲葉) 2023/03/06(月) 12:24:42

度々申し訳ございません。
ans(i + 1, cnt) = tmp(i) の部分がデータの数ぶんループしたあと「インデックスが有効範囲にありません。」のエラーがでてしまいます。
(マクロ勉強中) 2023/03/06(月) 13:29:11

データ数が6行なのにUbound(tmp)=65になってしまいます。
(マクロ勉強中) 2023/03/06(月) 13:33:28

 tmpは行数じゃなくて列数です。

 >'配列準備 [F1]はF列の列数(6)
 >ReDim ans(1 To [F1].Column, 1 To 1)
 この部分で列数決め打ちしてます。
 提示がF列まででしたので・・・。

 F列(6列)より列数が多くなる場合
 [F1].Column を [G1].Columnなどに変更いただくとよろしいかと思います。
 列数が決まっていなくて、転記先もいくら列増やしても大丈夫なようでしたら、
 10でも100でもリテラルな数値入れればエラーは出ないかと思います。

 コメント書き出しまでは実装してないです。

 CSVの中身が
 1200,支払い,3,改善して,12/23,2313
 2300,品揃え,4,,12/24,4234
 4500,対応,5,良かった,12/28,5837
 こういうデータの場合、1行目を読み込むとtmpの中身は以下のようになります。
 tmp(0) = 1200
 tmp(1) = 支払い
 tmp(2) = 3
 tmp(3) = 改善して
 tmp(4) = 12/23
 tmp(5) = 2313

 tmpをansに書き込むと、以下のようになります。
 ans(列,行) ※
 ans(1,1)= 1200     'tmp(0)
 ans(2,1)= 支払い   'tmp(1)
 ans(3,1)= 3        'tmp(2)
 ans(4,1)= 改善して 'tmp(3)
 ans(5,1)= 12/23    'tmp(4)
 ans(6,1)= 2313     'tmp(5)
 ※2次以上の配列の場合、動的に要素数を増やせるのは、最後の要素だけですので
 今回のように行数が分からない(EOF関数など)場合、行列を逆にしてデータを取り込みます。
https://excel-ubara.com/excelvba4/EXCEL284.html

 データを配列に取込終わった後に、セルに書き込めるように行列を逆転します。
https://excel-ubara.com/excelvba4/EXCEL258.html
 ans = Application.Transpose(ans)
 ans(行,列) ※
 ans(1,1)= 1200     'tmp(0)
 ans(1,2)= 支払い   'tmp(1)
 ans(1,3)= 3        'tmp(2)
 ans(1,4)= 改善して 'tmp(3)
 ans(1,5)= 12/23    'tmp(4)
 ans(1,6)= 2313     'tmp(5)

 最後に、Sheet2の最終行の次の行に取り込んだデータを出力します。
 j = .Range("A" & Rows.Count).End(xlUp).Offset(1).Row '★
 .Cells(j, 1).Resize(cnt, UBound(ans, 2)).Value = ans '★

(稲葉) 2023/03/06(月) 14:01:53


勉強不足ですみません。列数はかわらないです。
データ数的にUbound(tmp)=65はあっています。
ローカルウィンドウでans(6,1)="2313[F1]2300[A2]"
となっています。
コード上の変数は
ans(i[i=6]+1,cnt)=tmp(i)[=B2]2行目のタイミングで止まっているようです。
(マクロ勉強中) 2023/03/06(月) 14:17:20

 >データ数的にUbound(tmp)=65はあっています。
 66列あるわけですよね?

 なので
 >F列(6列)より列数が多くなる場合
 >[F1].Column を [G1].Columnなどに変更いただくとよろしいかと思います。
 >10でも100でもリテラルな数値入れればエラーは出ないかと思います。
 このように変更してほしいってことなんですけど・・・
(稲葉) 2023/03/06(月) 14:31:15

伝え方が間違ってました。申し訳ございません。
F列以上列が増えることはなく、6列×13行でtmp=65です。
(マクロ勉強中) 2023/03/06(月) 14:46:24

稲葉 様
マクロ正常に作動いたしました!
パソコンの不具合により作動しなかっただけみたいでした。
何度も対寧に答えてくださり助かりました。
本当にありがとうございます。
(マクロ勉強中) 2023/03/06(月) 15:26:45

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.