dポイントプレゼントキャンペーン実施中!

9項目で構成されているCSVがあります。
※このCSVはUTF-8、改行LFです。改行コードは可変ですが、UTF-8は変えたくありません。

1行目に項目名が、最下行7行にフッター行が入っています。

これを指定した行毎に分割したCSV保存を行いたいです。
(固定した方が簡単であれば10万行毎に分割したいです。)

・ファイル名は元のファイル名の末尾に「-1、-2、-3・・・」
・全てのファイルの1行目が項目行+レコード10万行+7行のフッターで構成したいです。

元のCSVファイルは100万行位あるため、
10万ずつ分割した場合、AAAA-1.csc ~ AAAA-11.csc の11ファイルに分割されます。

項目数に関わらず分割できると汎用性が高く非常に助かります。
よろしくお願いいたします。

A 回答 (7件)

#定数adTypeText忘れてた ;(



> :
> Const ForReading As Long = 1
> Const adSaveCreateOverWrite As Long = 2
Const adTypeText As Long = 2 '追加してください
> :
    • good
    • 0

なんかダブってますかね?


https://oshiete.goo.ne.jp/qa/11523302.html

Sub test()
  Dim wkCsv
  wkCsv = Application.GetOpenFilename("csv,*.csv,all,*.*")
  If VarType(wkCsv) = vbBoolean Then Exit Sub

  CreateObject("WScript.Shell").Run _
    "PowerShell -Command $i=0; Get-Content -ReadCount 100000 " _
    & wkCsv & " -Encoding UTF8 | % { $_ > dest$i.csv;$i++}" _
    , 0, True
  MsgBox "done"
End Sub

↑PowerShellをVBAから実行する感じも試してみたけどEncodingがうまくかず
よくわからなかったので、別スレで提示したFileSystemObjectのコードを応用↓

Sub test2()
  Dim wkCsv
  wkCsv = Application.GetOpenFilename("csv,*.csv,all,*.*")
  If VarType(wkCsv) = vbBoolean Then Exit Sub

  Const ForReading As Long = 1
  Const adSaveCreateOverWrite As Long = 2
  Const mx As Long = 100000
  Dim fs As Object 'Scripting.FileSystemObject
  Dim ts As Object 'Scripting.TextStream
  Set fs = CreateObject("Scripting.FileSystemObject")
  Set ts = fs.OpenTextFile(wkCsv, ForReading)

  Dim x As Long
  Dim y As Long
  Dim d As String

  d = Format$(Date, "yyyymmdd")
  ReDim ret(mx) As String

  ret(0) = ts.ReadLine
  Do Until ts.AtEndOfStream
    y = y + 1
    ret(y) = ts.ReadLine
    If y = mx Then
      x = x + 1
      With CreateObject("ADODB.Stream")
        .Open
        .Type = adTypeText
        .Charset = "UTF-8"
        .WriteText Join(ret, vbLf) & vbLf
        .SaveToFile d & Format$(x, "00000") & ".csv", adSaveCreateOverWrite
        .Close
        y = 0
      End With
    End If
  Loop
  ts.Close

  If y > 0 Then
    ReDim Preserve ret(y)
    With CreateObject("ADODB.Stream")
      .Open
      .Type = adTypeText
      .Charset = "UTF-8"
      .WriteText Join(ret, vbLf) & vbLf
      .SaveToFile d & Format$(x + 1, "00000") & ".csv", adSaveCreateOverWrite
      .Close
    End With
  End If
End Sub

#本スレは別スレついでの手法提案みたいなものなので、
#動かなかったり望む結果が得られなかったとしてもあまり深追いするつもりはありません
    • good
    • 0
この回答へのお礼

ありがとうございます。

これはつまり、test2だけを標準モジュールに入れて試せば良いんですかね?
後程試してみます。

お礼日時:2020/03/11 14:01

No4です。



<おまけ情報>

int main(int argn, char *argv[])
{
FILE *fpin,*fpout;
fpin = fopen(argv[1],"r");

とすると、
 コンパイルして出来たEXE(実行)ファイルにドラッグしたファイルが fpin でオープンされるので、この種のプログラムでは、ターミナルを開かなくても使えて便利ですよ。
    • good
    • 0
この回答へのお礼

一度作っておけば他の環境で使えるわけですね。
試すのが楽しみです。
ありがとうございます。

お礼日時:2020/03/11 14:00

>C言語環境を準備するには何が必要でしょうか?低コストだと助かるのですが。



マイクロソフトのVisualStudioが一般的ですが、
東海大の安江研究室で開発したフリーのVisual Windows for BC++
も軽いので愛用しています。

https://www.vector.co.jp/soft/winnt/prog/se32660 …
    • good
    • 0
この回答へのお礼

C言語挑戦してみるかもしれません。大昔にBASICをかじったことがある程度です。
ありがとうございます。

お礼日時:2020/03/11 13:59

フッターとデータの区別は何かありますか?


例えばフッターの初めの行には「,」が無いとか?
    • good
    • 0
この回答へのお礼

ありがとうございます。
たった今、仕様が変更になりました。
本件、手作業で行っていたものですから、負荷軽減のため元のCSVはフッターなしの状態で提供されることとなりました。
つまり、項目行+約100万件のCSVを、項目行+10万行ずつ、つまり100,001行ずつのCSVに分割することになります。
テキストエディタで切り分けていく作業を軽減したいです。
ちなみに毎週少しずつ増加していくので現在10ファイルに分割していたのがいずれ11ファイルになります。
よろしくお願いいたします。

お礼日時:2020/03/03 21:13

>項目数に関わらず分割できると汎用性が高く非常に助かります。


ExcelVBAでなく、Cで簡単なプログラムを作成して走らせたほうが早い気がします。

関数としては、「標準入力からN行読み取って、ファイル名XXに書き出す」というのを作って、メインからは、それを入力がある限り、ファイル名を変えながら呼び続けるということでしょうかね。
    • good
    • 0
この回答へのお礼

C言語環境を準備するには何が必要でしょうか?低コストだと助かるのですが。

お礼日時:2020/03/03 18:50

念のために確認ですが


① BOM 付きで保存でしょうか?それとも BOM 無での保存でしょうか?
② 変換後の全行数は最大で 100,008 行 という事でしょうか?
③ 変換後の拡張子は「.csc」ではなく「.csv」で良いのですよね?
④ 元ファイルと同じフォルダーに作成すれば良いのですよね?
⑤ 重複ファイルが有った場合は上書き保存で良いのですよね?
⑥ 上書き保存の場合元々のファイル数より小さくい場合、番号の大きなファイルが残りますが、それでも良いですか?
    • good
    • 0
この回答へのお礼

ありがとうございます。
①BOMを理解してなかったのですが秀丸を見たところ、無くて良いです。
②はい。100,008行となります。もしフッターがないパターンのCSVが発生した場合ソース調整で何とかなりますよね?
③誤入力で失礼しました。CSVです。
④はい、同じフォルダーが分かりやすくて良いです。
⑤⑥きちんと空のフォルダ内で実行する想定なので現状のフォルダの状況を無視して上書きで結構です。
よろしくお願いいたします。

お礼日時:2020/03/03 18:49

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています