LoginSignup
loweststrata
@loweststrata

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

VBAでCSV出力を行った際にハイフンで書式設定した日付が/に変換されるのを防ぎたい

解決したいこと

ここに解決したい内容を記載してください。

初心者ですみません。
会社のCSVファイルをアップロードを行う専用サイト向けに
色んなサイトのソースコードを元にEXCEL→CSVに変換できるファイルを作成しました。

そこまでは良かったのですが「I」「J」列の部分をハイフンで区切った
日付にしているのですが出力後に/になってしまいます。
※確認する際はメモ帳で開いて確認をしています。

または、問題・エラーが起きている画像をここにドラッグアンドドロップ
元のEXCEL画面.png

該当するソースコード

ソースコードを入力

Sub CSV出力()

Dim file As String
Dim eRow As Long, eCol As Long
Dim data As Variant
Dim i As Long, j As Long

currentTime = Format(Now(), "yyyy-mm-dd_hh-mm-ss")
Filename = "xxxx_C1&currenttime&.csv"

file = ThisWorkbook.Path & "\xxxx_C1.csv"

eRow = Cells(Rows.Count, "A").End(xlUp).Row
eCol = Cells(1, Columns.Count).End(xlToLeft).Column
data = Range(Cells(1, 1), Cells(eRow, eCol)).Value

Open file For Output As #1

For i = 1 To UBound(data, 1)
Print #1, CStr(data(i, 1));
For j = 2 To UBound(data, 2)
Print #1, "," & data(i, j);
Next j
Print #1, vbCrLf; 'vbCr vbLf
Next i

Close #1

MsgBox "完了"

End Sub


### 自分で試したこと
ここに問題・エラーに対して試したことを記載してください。
普通にcsvタブ区切りで保存すればいいのですが工数削減のため
マクロで何とか解決をしたいです。
0

4Answer

I列、J列は、Text関数(式)を出力する方法もあります。

Print #1, ",""=TEXT(" & data(i, j) & ",""DD-MM-YYYY"")""";

1

Comments

  1. @loweststrata

    Questioner

    ありがとうございます!
    早速頂いたものを入れてみましたが
    全体に入ってしまいました・・・

    挿入する場所が違いますかね?
    申し訳ありません・・画像1.png

  2. I列とJ列だけ 上のコードで、それ以外は、今までのPrint #1, "," & data(i, j); です。
    日付の列を判定してください。

  3. スクリーンショットを見ると=TEXT(...と表示されているので、式と認識されずに文字列扱いになってしまっています。
    おそらくCSVファイル内では...,"TEXT(2024/05/22,"DD-MM-YYYY")",...のようになっていて、二重引用符が入れ子になっているため式として解釈できないようです。

    手元で確認できないのですが
    出力したいCSVファイルの内容...,"TEXT(2024/05/22,""DD-MM-YYYY"")",...
    そのために書くべきVBAのコードPrint #1, ",""=TEXT(" & data(i, j) & ",""""DD-MM-YYYY"""")""";
    となるような気がします。

  4. @loweststrata

    Questioner

    @nak435 さん
    @albireo さん

    ありがとうございます!
    ホントすみません・・・
    I、J列の指定はどのようにすれば良いでしょうか

    Rangeなるものを見つけたので入れてみましたがより結果がおかしくなってしまいました・・

    For i = 1 To UBound(data, 1)
    Print #1, CStr(data(i, 1));
    For j = 2 To UBound(data, 2)

    Print #1, Range("I:J").Select; ",""=TEXT(" & data(i, j) & ",""""DD-MM-YYYY"""")""";

    Next j
    Print #1, vbCrLf; 'vbCr vbLf
    

    Next i

    2回目.png

    ◆画像のコード
    Sub CSV出力()

    Dim file As String
    Dim eRow As Long, eCol As Long
    Dim data As Variant
    Dim i As Long, j As Long

    currentTime = Format(Now(), "yyyy-mm-dd_hh-mm-ss")
    Filename = "xxxx_C1&currenttime&.csv"

    file = ThisWorkbook.Path & "\xxxx_C1.csv"

    eRow = Cells(Rows.Count, "A").End(xlUp).Row
    eCol = Cells(1, Columns.Count).End(xlToLeft).Column
    data = Range(Cells(1, 1), Cells(eRow, eCol)).Value

    Open file For Output As #1

    For i = 1 To UBound(data, 1)
    Print #1, CStr(data(i, 1));
    For j = 2 To UBound(data, 2)
    Print #1, ",""=TEXT(" & data(i, j) & ",""""DD-MM-YYYY"""")""";

    Next j
    Print #1, vbCrLf; 'vbCr vbLf
    

    Next i

    Close #1

    MsgBox "完了"

    End Sub

  5. 質問内容の冒頭のコードをベースに書き換えると、以下のコードになります。

    Sub CSV出力()
    
        Dim file As String
        Dim eRow As Long, eCol As Long
        Dim data As Variant
        Dim i As Long, j As Long
    
        'currentTime = Format(Now(), "yyyy-mm-dd_hh-mm-ss")
        Filename = "xxxx_C1&currenttime&.csv"
    
        file = ThisWorkbook.Path & "\xxxx_C1.csv"
    
        eRow = Cells(Rows.Count, "A").End(xlUp).Row
        eCol = Cells(1, Columns.Count).End(xlToLeft).Column
        data = Range(Cells(1, 1), Cells(eRow, eCol)).Value
    
        Open file For Output As #1
    
        For i = 1 To UBound(data, 1)
            Print #1, CStr(data(i, 1));
            For j = 2 To UBound(data, 2)
                If i > 1 And (j = 9 Or j = 10) Then
                    Print #1, ",""=TEXT(" & Cells(i, j).Value2 & ",""""DD-MM-YYYY"""")""";
                Else
                    Print #1, "," & Cells(i, j);
                End If
            Next j
            Print #1, vbCrLf; 'vbCr vbLf
        Next i
    
        Close #1
    
        MsgBox "完了"
    
    End Sub
    
  6. @loweststrata

    Questioner

    @nak435さん

    If i > 1 And (j = 9 Or j = 10) Then

    このように列を指定するんですね!
    大変勉強になりました。

    頂いたコード完璧に動作しました・・・!

    本当にありがとうございました!

  7. Cells(i, j).Value2としなければ、日付のシリアル値が取得できないところがミソです。

    解決でよければ、当Q&Aをクローズしてください。

Excelは読み込んだ際にセル内の文字列が数値や日付として解釈されるものなら変換します。
これはCSVファイルを開くときに勝手に行われるので、CSVファイルを作る側で対処することはできません。
(テキストインポートウィザードというものもありますが、手順が面倒な上に今では「互換性のために残しているレガシー機能」だそうです)

一応Print #1, ",'" & data(i, j);とセルの先頭部分にシングルクォートをつけることで日付文字列とは認識させないようにする、といったすっきりしない回避策ならあります。

1

I列、J列の値が内部では
シリアル値で保存されているのでは?
(セル表の示形式で標準にすると、数値がシリアル値が見れるはず)

I列、J列の値を読みとるときに、随時、
再度Format関数で任意の書式の文字列に再変換し、
文字列型でファイルに書き出してみては?

0

一つ前のQ&Aはすでにクローズされていますが、回答が付いていないので、Q&A自体を「削除」することができます。
(Q&Aを「取り下げた」と想定しました。一つ前のQ&Aが「削除」されたら、この回答も「削除」します。)

0

Your answer might help someone💌