[[20180914142655]] 『大量のcsvからスペースをとりたい』(シロ) ページの最後に飛ぶ

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

 

『大量のcsvからスペースをとりたい』(シロ)

ご相談なのですが、
何万件と入ったcsvデータが複数ございまして、
45列目と85列目が郵便番号なのですが、
例)999-999 ←スペース
のスペースを無くしたいのと

999ー999

と全角のハイフンを半角のハイフンに修正する
のにマクロなどで時間短縮できないでしょうか?

直したいのは45列目の注文者郵便番号1
と85列目の送付先郵便番号1

です。

宜しくお願い致します。

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


2列くらいだったら、列指定した置換でできないでしょうか?
(ゆ) 2018/09/14(金) 14:34

ご返答ありがとうございます。
置換でしておりましたが、量が多いためマクロで
複数のファイルを順番に一気にできないかと思いご相談させて頂きました。
宜しくお願い致します。
(シロ) 2018/09/14(金) 14:40

マクロを使うとして、
プランA
CSVをいったんブックとして開いて、編集後、CSV形式で上書き保存する

プランB
CSVをテキストファイルとしてシート上にインポートして、編集後、作業結果のシートをCSV形式で保存する

プランC
マクロ上でテキストデータをメモリ上に直接読み込み、編集後、ファイルに出力したい。
(ブック、シートは関係ない)

のどれなんでしょうか?
ちなみに、比較したことないので、どれが良いかはわからないですけど、いろいろ勉強になりそうなのはB案でしょうか・・

お手軽ならA案ですけど、「0123」→「123」や「1/4」→「1月4日」のようにExcel君が”標準”と思っている形式に勝手に変更されたりといった弊害が出る可能性があります。
(もこな2) 2018/09/14(金) 15:08


もこな2さん、
ご返信誠に有難うございます。

ご提案頂いた
プランbでお願いできますでしょうか?

プランaはブックとして開くと確かに弊害がでそうですね。。
宜しくお願い致します。
(シロ) 2018/09/14(金) 15:31


>プランbでお願いできますでしょうか?
いや、作ってあげるって意味じゃないですよ。

プランBでいくならいくで、どこまで自分でできるのか(わかるのか)、作りかけでいいので見せてもらわないと話がすすみません。
(もこな2) 2018/09/14(金) 16:38


そうでしたか。
マクロ初心者のため出来かねます。

あまりに量が多いためこちらにヘルプをだしてみました。

他にもしご回答いただける方がいらっしゃればお力添えをお願い致します。
(シロ) 2018/09/14(金) 16:46


作業依頼場でなく、あくまで質問掲示板ですからね
マクロ初心者なら、マクロの記録を使ってどんな感じになるか確かめてみるとよいです
それでどこら辺がわからないか質問すると良いです
もこな2さんのa案なら、マクロ記録を使えば多少の手直しだけで簡単に出来るような気がします
一旦それで確かめてみるのもいいかもです
(ゆ) 2018/09/14(金) 17:30

Sub main()'プランC
    Dim Oldfile As String, Newfile As String, intFF As String, Outff As String
    Oldfile = Application.GetOpenFilename(FileFilter:="CSV ファイル ,*.csv", FilterIndex:=1, Title:="CSVファイルを選択してください", MultiSelect:=False)
    If VarType(Oldfile) = vbBoolean Then Exit Sub
    Newfile = Replace(Oldfile, ".csv", "new.csv")
    intFF = FreeFile
    Open Newfile For Output As #intFF
        Outff = FreeFile
        Open Oldfile For Input As #Outff
            Do Until EOF(Outff)
                Line Input #Outff, buf
                newbuf = Replace(Replace(buf, Split(buf, ",")(44), StrConv(Trim(Split(buf, ",")(44)), vbNarrow)), Split(buf, ",")(84), StrConv(Trim(Split(buf, ",")(84)), vbNarrow))
                Print #intFF, newbuf
            Loop
        Close #Outff
    Close #intFF
    MsgBox Newfile & "として保存しました。"
End Sub
(mm) 2018/09/14(金) 17:38

mmさんがわざわざ時間をかけて作ってくれたコードで解決すれば良いですが、ご自分でマクロを書く気がないならば、列をクリックして範囲指定後、CTRL+Fとし、「置換」タグからスペース文字を無くすとか、ハイフンを指定するとかして「全て置換」。 こうやって手作業で直せば良いと思います。 1ファイルに2列ずつですし、大して時間はかかりませんよね? コーディングする時間より早そうです。(他人に労働させようとするのは、質問とは言いません)
(???) 2018/09/14(金) 17:43

たくさんのご意見誠に有難うございます。
mmさん、お時間取らせてしまい申し訳ございません。
自分なりに上記のコードを解析してみます。

???さん、初めましてなのにその口の利き方はなんですか?
他の質問掲示板でも随分辛口みたいですが。

ただ文句いいたいだけならそもそもここにこなければいい。
(シロ) 2018/09/14(金) 18:22


B案(プランB)もマクロの記録を使えば、基本部分はできるとおもうので、ちょっとずつでも頑張る気がわいたらやってみてください。

あと、複数のCSVと言ってるだけで、実際にはいくつあるのかわかりませんが、100ファイルとかあったら、A案もB案も

 (1)開く(インポートする)
 (2)マクロなり手動なりで作業する
 (3)保存(して閉じる)

を100回繰り返すことになるので、おっしゃる通り一通りの作業をマクロ化したほうがよいとは思います。

その場合、開きたいCSVファイルのフルパス(少なくともファイル名)を取得する必要がでてきますが、
Excel ファイル一覧 なんてキーワードでネット検索すると手ごろな情報があるとおもいますので当たってみてください。
(あくまで、自分でマクロを作ろうとした場合です。)
(もこな2) 2018/09/14(金) 18:29


もこな2さん、
アドバイス頂き誠に有難うございます。

マクロを自分で作ろうとしております。
量が多いので一つ一つ置換するよりマクロ化したほうが良いと当方も思いました。

プランcのマクロをデバックすると、
bufとnewbufの変数が宣言されていないとでましので、

buf As String, newbuf As String
を追加したところそのエラーは回避されました。

次のエラーが
newbuf = Replace(Replace(buf, Split(buf, ",")(45), StrConv(Trim(Split(buf, ",")(45)), vbNarrow)), Split(buf, ",")(85), StrConv(Trim(Split(buf, ",")(85)), vbNarrow))

ここでインデックスが有効範囲にないとエラーがでました。

ここのエラーがなにを意味するのか分かりません。。

(44) と (84)というのが列番号を指定しているのでしょうか?

(シロ) 2018/09/14(金) 18:35


え〜と ^^
多分ですが、Splitは配列を返していると思いますので、buf As String, newbuf As String
ではなく
buf, newbuf

バリアントにしてみてください。
読込CSVが間違っていなければ完璧動作すると思いますです。はい ^^;
>>(44) と (84)というのが列番号を指定しているのでしょうか?
配列の添え字で、AS列、CG列のデータに相当するはずだと思います。。。多分
動作確認まで。
詳しい事は他の方の回答をお待ちくださいね。
m(__)m
でわ

(隠居じーさん) 2018/09/14(金) 20:20


 シロさん
 buf, newbuff はString型でOKです。

 ただ、空白行、若しくは列数が84に満たない行があるとエラーになります。

 そのnewbuff=の変換が期待通りの変換になるかは不明ですが、
 その行の前で 
 1) buffが空白でないか
 2) 空白でなければ、列数が満たされているか
 を確認する必要があります。
 空白は

 1) は If buf <> ""
 2) は新たに変数を設けて(例えばx) x=split(buf,",")
    として、Ubound(x)が84以上であれば変換する。

 でしょう...

(seiya) 2018/09/14(金) 20:36


>>buf, newbuff はString型でOKです。
確かに! ^^v
確認いたしました。
シロさん
すみません!

seiyaさん
いつもありがとうございます
m(__)m

(隠居じーさん) 2018/09/14(金) 20:47


seiyaさん、隠居じーさん、
ご回答誠にありがとうございます!

csvのデータは150列ほどございまして、どこかの列で空白があるかもしれせん。
明日以降になりますが、実施してみます!
(シロ) 2018/09/14(金) 20:57


C案で進めるならそのままで頑張ればよいとおもいますが、個人的には始めてマクロつくってみます!といってる状態だと少々ハードル高いような気がします。

メモリ上で処理するから実行速度は速いでしょうけど、シート上で何か処理をするわけではないので、ステップ実行しても目視確認できませんし、”マクロの記録”も使えません。

また。???さんのコメントを再度よく見てください。
めちゃくちゃ正攻法書いてありますよ。A案、B案はマクロでそれをやるだけです。
こちらは、マクロの記録でExcel君にベースとなるコードを書いてもらうことができます。

CSVファイルが同じフォルダに全部入っていて、レイアウトが全部一緒ということであれば、
【B案】であれば

 (0) ブックに”作業用”というシートを用意しておく(手作業)

 (1) どうにかして、Excel君にCSVが入っているフォルダを伝える
 (2) 対象フォルダの中からCSVファイル(*.csv)を探す
 (3) "作業用"シートの内容をクリアする
 (4) "作業用"シートにA1以降「テキストファイル」の取り込みで見つかったCSVを取り込む
 (5) 対象列の" "と""、"−"と"-"をそれぞれ置換
 (6) "作業用"シートの内容をCSV形式かつ、見つかったファイル名で上書き保存する。
 (7) 次のファイルを探して、(3)〜(6)を繰り返す【ループ処理】

こんな感じになるとおもいますし、ちょっと分かりづらいかもしれませんが、”マクロの記録”を使うと、(3)〜(6)まではベースとなるコードはExcel君が書いてくれます。

 ※もちろん、そのままではよくないので、コードの意味をしらべて要らない記述を削除したり、
  ファイル名などが固定されてしまうので、そこを"変数"に置き換えていく作業(コーディング)は
  必要になります。

また、(1)〜(2)は、A案、B案、C案どれでも必要になりますが、先に言ったように、ヒントはいくらでもネット上にあるとおもいので、とりあえず割愛します。

このほか、ご自身で作る気があるなら、↓はやめたほうがいいですよ。わたしも、丸投げ(作業依頼)だと思いましたので・・・・
>マクロ初心者のため出来かねます。

この掲示板の規約では質問という名の作業依頼を禁止してないようですので、別にそういう投稿でもいいのかもしれないですけど、あんまり作業依頼系に回答が付いた例を見ません。
なので、とりあえず書いてみて、うまく動かないなら、どういう風に動くと思っていたのにどうなってしまったのか(エラーが出るならどのようなエラーなのか)をピンポイントで聞くと、丁寧な解説付きで答えが得られると思いますので頑張ってみてください。

長文失礼しました。

(もこな2) 2018/09/15(土) 09:04


 くどい!
 この掲示板ではマルチポストも基本的には禁止をしていない。
 質問をしたいものが質問をし、回答したいものがその理由に関わらず回答する。
 回答したくなければ、そのスレを無視すればよいだけ!
(seiya) 2018/09/15(土) 09:38

seiyaさん

ご質問です。

 1) は If buf <> ""

こちらはbufが空白であるかをif関数で処理するためと思っているのですが、
どこにこのコードをつけたせば宜しいのでしょうか?

 Do Until EOF(Outff)
                Line Input #Outff, buf
                If = buf <> ""

こちらにつけてみましたが、赤字になりましたのでエラーがでました。

2) は新たに変数を設けて(例えばx) x=split(buf,",")

    として、Ubound(x)が84以上であれば変換する。

こちらですが、新たに変数を x as string と追加して、
newbuf = Replace(Replace(buf, Split(buf, ",")(45), StrConv(Trim(Split(buf, ",")(45)), vbNarrow)), Split(buf, ",")(89), StrConv(Trim(Split(buf, ",")(89)), vbNarrow))

こちらの上に入れてみました。
ubound関数は調べてみましたが、なかなか理解ができません。。

処理したいcsvは大量にございますが、列は151で何列かに空白しかない列が存在するのは
同じでした。

処理したい列は再確認しましたところ、45と89列目でした。

なので、

Sub pranc()

    'プランC
    Dim Oldfile As String, Newfile As String, intFF As String, Outff As String, buf As String, newbuf As String, x As String
    Oldfile = Application.GetOpenFilename(FileFilter:="CSV ファイル ,*.csv", FilterIndex:=1, Title:="CSVファイルを選択してください", MultiSelect:=False)
    If VarType(Oldfile) = vbBoolean Then Exit Sub
    Newfile = Replace(Oldfile, ".csv", "new.csv")
    intFF = FreeFile
    Open Newfile For Output As #intFF
        Outff = FreeFile
        Open Oldfile For Input As #Outff
            Do Until EOF(Outff)
                Line Input #Outff, buf
                If = buf <> ""
                x = Split(buf, ",")
                newbuf = Replace(Replace(buf, Split(buf, ",")(45), StrConv(Trim(Split(buf, ",")(45)), vbNarrow)), Split(buf, ",")(89), StrConv(Trim(Split(buf, ",")(89)), vbNarrow))
                Print #intFF, newbuf
            Loop
        Close #Outff
    Close #intFF
    MsgBox Newfile & "として保存しました。"
End Sub

と当方では今修正しております。

理解不足のため質問内容にも違和感を感じられるかもしれません。。
ご返答頂きますと幸いです。

宜しくお願い致します。

(シロ) 2018/09/15(土) 15:03


 x はVariant型ですので 変数宣言は Dim x のようにデータ型は指定しなくて構いません。

 多分

    Open Newfile For Output As #intFF
        Outff = FreeFile
        Open Oldfile For Input As #Outff
            Do Until EOF(Outff)
                Line Input #Outff, buf
                newBuf = buf
                If = buf <> "" Then
                    x = Split(buf, ",")
                    If Ubound(x) >= 89 Then
                	newbuf = Replace(Replace(buf, Split(buf, ",")(45), StrConv(Trim(Split(buf, ",")(45)), vbNarrow)), Split(buf, ",")(89), StrConv(Trim(Split(buf, ",")(89)), vbNarrow))
                    End If
                End If
                Print #intFF, newbuf
            Loop
        Close #Outff
    Close #intFF

 こんな感じになると思います。
(seiya) 2018/09/15(土) 15:28

seiyaさん

早速のご回答誠に有難うございます。

If = buf <> "" Then
の箇所が構文エラーとなります。

end if

もございますし、どこがおかしいのでしょうか・・
(シロ) 2018/09/15(土) 15:43


 おっと、= を削除して下さい。
 If buf <> "" Then 
(seiya) 2018/09/15(土) 15:49

seiyaさん

=を削除でエラー回避できました!

新たに
x が変数宣言されておりませんとでました。

Variant型は宣言しなくても良いというお話でしたが
こちらは設定でエラー回避か何かされているということでしょうか??
(シロ) 2018/09/15(土) 15:55


 Split関数から生成されるデータ型はVariant型でなくてはならないからです。
 宣言の仕方は

 Dim x 又は, Dim x As Variant

 As 以降は省略できる、という意味です。

 Dim x() As String
 という宣言の仕方もありますが、今回は使用しません。
(seiya) 2018/09/15(土) 16:08

seiyaさん

as以降の省略理解致しました。
有難うございます。

ご報告ですがエラーはでなくなりましたが、
テストで処理前と処理後の45と89列目の
スペースを確認致しましたが、なくなっておりませんでした。

エラーはでていないので、なにかプログラムが足りないのでしょうか。。
(シロ) 2018/09/15(土) 20:17


 そのcsvをエクセルで開いたとき、Trim関数で除去できるものですか?

 出来たらcsvの対象スペースを削除したい数行を
 (既存のデータは適当に変更してもスペースは変更せずに)
 提示してもらうと分かりやすいと思います。
(seiya) 2018/09/15(土) 20:28

念のためですけど、Splitの返り値の配列は 0オリジンですよね。
そこは大丈夫ですか?
1列目は 0を指定しますし、
10列目は、9を指定します。
そのあたりに誤解はないですか?

(γ) 2018/09/15(土) 20:45


 >念のためですけど、Splitの返り値の配列は 0オリジンですよね。

 >(44) と (84)というのが列番号を指定しているのでしょうか? 
 >(シロ) 2018/09/14(金) 18:35 

 この辺のやり取りは見逃していました。
 γさんのご指摘の通りSplit関数で返されるのは 0-Base (添え字が0から始まる)の配列です。
 ですので実際の列番号から1を引く必要があります。
(seiya) 2018/09/15(土) 20:56

>>と全角のハイフンを半角のハイフンに修正する

半角になったか確認されると処理対象列違いかどうか
は確認できませんでしょうか。
半角に変換されていれば
seiyaさんご指摘のTrimで除去出来ない何かの可能性が大では
(隠居じーさん) 2018/09/15(土) 21:14

ご返信が遅くなり申し訳ございません。
たくさんのご意見誠に有難うございます。

seiyaさん

処理したい列二つだけを抽出し40行まで絞って置換したいものと問題ないものが入っているものを
こちらに貼り付けます。

番号1,番号2
233-0006,170-0011
668-0263 ,668-0263
〒 006-0815 ,〒 006-0815
319-1541 ,319-1541
031-0000, 031-0823
890-0031,890-0026
124-0006,124-0006 
635-0074 ,635-0074
274-0073,274-0074
192-0031,519-3922
247-0009, 084-0903
894-0015,897-0031
799-1301 ,799-1301
530-0015, 531-0071
253-0042,251-0057
253-0042,251-0057
593-8301,593-8312
350-1142,350-1302
648-0084,649-7121
277-0031,277-0031
130-0011,130-0011
359-1145,359-1145
699-0406,699-0406
981-0501,981-0501
193-0835,193-0835
193-0835,193-0835
193-0835,193-0835
731-0213,731-0213
720-0832,720-0832
960-0231,960-0231
511-0033,511-0033
511-0811,511-0068
511-0811,511-0068
981-3311,981-3301
981-3311,981-3301
154-0016,158-0097
702-8044,702-8044
980-0814,980-0814
980-0814,980-0814

このようにスペース(半角、たまに全角)とハイフンもたまに全角があります。
一つ郵便番号の記号が入ってしまっておりますが、、こちらもできれば置換したいです。

列番号を45と89にしていたので、1引いて44と88でマクロを実行してみましたが、スペースなどは
消えておりませんでした。

上記の処理したい番号達はエクセルで開いてtrim関数でスペースが消えるのは確認致しました。

宜しくお願い致します。
(シロ) 2018/09/17(月) 10:04


 では、思い切って

 >               Line Input #Outff, buf
 >               If = buf <> ""
 >               x = Split(buf, ",")
 >               newbuf = Replace(Replace(buf, Split(buf, ",")(45), StrConv(Trim(Split(buf, ",")(45)), vbNarrow)), Split(buf, ",")(89), StrConv(Trim(Split(buf, ",")(89)), vbNarrow))
 >               Print #intFF, newbuf
 >           Loop

 の部分を

                Line Input #Outff, buf
                If buf <> "" Then buf = Join(Application.Trim(Application.Asc(Split(buf, ","))), ",")
                Print #intFF, buf
            Loop

 に変更してみてください。
 ちなみに、変数 newbuff と x は使用しません。

(seiya) 2018/09/17(月) 11:01

 編集: 「このようにスペース(半角、たまに全角」を見逃し。 11:21

seiyaさん

上記のコードに修正すると

buf = Join(Application.Trim(Application.Asc(Split(buf, ","))), ",")

ここで型が違いますというエラーがでます。

bufのstringに問題があるのでしょうか?
(シロ) 2018/09/17(月) 11:44


 単一列に255以上の文字列が存在するのですね。
 以下で試して下さい。

  >               Line Input #Outff, buf
 >               If = buf <> ""
 >               x = Split(buf, ",")
 >               newbuf = Replace(Replace(buf, Split(buf, ",")(45), StrConv(Trim(Split(buf, ",")(45)), vbNarrow)), Split(buf, ",")(89), StrConv(Trim(Split(buf, ",")(89)), vbNarrow))
 >               Print #intFF, newbuf
 >           Loop

 の部分を

                Line Input #Outff, buf
                buf = myTrim
                Print #intFF, buf
            Loop

 として、以下のコードを新たに End Sub の後に加えてください

 Function myTrim(ByVal txt As String) As String
      With CreateObject("VBScript.RegExp")
          .Global = True: .MultiLine = True
          .Pattern = "[  ]+(?=(,|$))"
          myTrim = Replace(.Replace(txt, ""), "ー", "-")
     End With
 End Function
(seiya) 2018/09/17(月) 12:23

seiyaさん

引数は省略できません
というエラーが

buf = myTrim
の箇所ででております。

こちらの対処方法が分かりかねます。

宜しくお願い致します。
(シロ) 2018/09/17(月) 13:12


 失礼しました...

 そこは

 buf = myTrim(buff)

 にしてください。
(seiya) 2018/09/17(月) 13:16

seiyaさん

 buf = myTrim(buff)
こちらbuff⇒bufに修正して処理をすればエラーはなくなりましたが
宜しかったでしょうか?

処理結果ですが、スペースは消えておりませんでした。

お渡ししたtestのcsvでするとa,b列とも末尾のスペースは消えておりましたが文頭の
スペースは消えておりませんでした。

元のデータ151列あるcsvに何かお伝えしなければならないことがあるのでしょうか。。
(シロ) 2018/09/17(月) 13:28


 ということは、何らかの変化は見られたのですね。

 新たに追加したコードを以下に差し替えて試してください。

 Function myTrim(ByVal txt As String) As String
      With CreateObject("VBScript.RegExp")
          .Global = True: .MultiLine = True
          .Pattern = "[  ]+(?=(,|$))"
          txt = .Replace(txt, "")
          .Pattern = "(^|,)[  ]+"
          myTrim = StrConv(.Replace(txt, "$1"), 8)
     End With
 End Function
(seiya) 2018/09/17(月) 13:35
 編集あり 15:55

seiyaさん

test用の2列しかないcsvだと今回も変化はございました。
文頭のスペースも消えております。

しかしながら151列ある方のcsvは変化なしでした。

こちらはエクセルでいうとa列の1行目から順に
スペースを探して消していくというコードでしょうか?

列が多い方だとうまくいかないので、他の列の空白や日付などなにか邪魔しているものが
あるのでしょうか。。
(シロ) 2018/09/17(月) 14:19


 列数には影響されないはずです。
 提示されたデータを200列にして試しましたが、期待通りでした。

 新規ブックを立ち上げて下記コード単体で試してください。

 Sub test()
     Dim a, e, txt As String, ff As Long
     a = Application.GetOpenFilename("CSVFiles,*.csv", , , , True)
     If Not IsArray(a) Then Exit Sub
     With CreateObject("VBScript.RegExp")
         .Global = True: .MultiLine = True
         For Each e In a
             txt = CreateObject("Scripting.FileSystemObject").OpenTextFile(e).ReadAll
             .Pattern = "(^|,)[  ]+"
             txt = .Replace(txt, "$1")
             .Pattern = "[  ]+(?=(,|$))"
             ff = FreeFile
             Open Replace(e, ".csv", "_Trimmed.csv") For Output As #ff
                 Print #ff, .Replace(txt, "")
             Close #ff
         Next
     End With
 End Sub
(seiya) 2018/09/17(月) 15:02

seiyaさん

上記のコードでも151列のデータではスペースは消えませんでした。

testで適当に20列ぐらいに減らして実行すると
なぜかスペースは消えておりました。

掲示板なので151列あるデータを見て頂きたいですが、すべてはご提示できません。。

(シロ) 2018/09/17(月) 15:18


 >上記のコードでも151列のデータではスペースは消えませんでした。 
 全列、全く消えないのですか?それとも消える列と消えない列があるのですか?

(seiya) 2018/09/17(月) 15:32


seiyaさん

最初に申し上げました、45と89列目のみ
スペースを排除したいので、そちらの列のみ確認しております。

他の列は例えば日時が入っている箇所 2018/09/09 12:00
とスペースが入っていて問題ない列もございます。

流れと致しましては、様々な情報が入っているcsvのデータ(一列目の項目は全て一緒のため151列)
の45と89列目をスペースがなくハイフンが半角にして保存という流れです。

そのスペースやハイフンのせいで既存のシステムにアップロードするとエラーがおきてしまいます。。
ご説明が下手で申し訳ございません。

(シロ) 2018/09/17(月) 15:52


 45列目であろうと、89列目であろうと変化が無いということはそれは「スペース」では無いということです。

 >上記の処理したい番号達はエクセルで開いてtrim関数でスペースが消えるのは確認致しました。
 これは間違いないですか?
(seiya) 2018/09/17(月) 16:02

seiyaさん

上記の処理したい番号はtrim関数で消えるのは私の方でも確認致しました。
こちらは間違いないです。
(シロ) 2018/09/17(月) 16:05


 このコードはその位置に限らず、全ての半角・全角スペースを消します。
 これでどうなるか見てください。

 Sub test()
     Dim a, e, txt As String, ff As Long
     a = Application.GetOpenFilename("CSVFiles,*.csv", , , , True)
     If Not IsArray(a) Then Exit Sub
     With CreateObject("VBScript.RegExp")
         .Global = True: .MultiLine = True
         For Each e In a
             txt = CreateObject("Scripting.FileSystemObject").OpenTextFile(e).ReadAll
             .Pattern = "[  ]+"
             ff = FreeFile
             Open Replace(e, ".csv", "_Trimmed.csv") For Output As #ff
                 Print #ff, .Replace(txt, "")
             Close #ff
         Next
     End With
 End Sub
(seiya) 2018/09/17(月) 16:15

seiyaさん

上記のコードでしたらスペースは消えておりました!
他の列も全てです!
(シロ) 2018/09/17(月) 16:22


 問題はカンマの前後のスペースですよね。

 >             .Pattern = "[  ]+"
 を
             .Pattern = "[  ]+(?=(,|$))"
 にして試して下さい。
 カンマの前のスペースだけを除去しますので確認してください。

(seiya) 2018/09/17(月) 16:38


seiyaさん

こちらのコード

 Sub test()
     Dim a, e, txt As String, ff As Long
     a = Application.GetOpenFilename("CSVFiles,*.csv", , , , True)
     If Not IsArray(a) Then Exit Sub
     With CreateObject("VBScript.RegExp")
         .Global = True: .MultiLine = True
         For Each e In a
             txt = CreateObject("Scripting.FileSystemObject").OpenTextFile(e).ReadAll
             .Pattern = "[  ]+"
             ff = FreeFile
             Open Replace(e, ".csv", "_Trimmed.csv") For Output As #ff
                 Print #ff, .Replace(txt, "")
             Close #ff
         Next
     End With
 End Sub


             .Pattern = "[  ]+(?=(,|$))"
に修正でお間違いないでしょうか?

処理してみましたがスペースは消えておりませんでした。

(シロ) 2018/09/17(月) 16:52


ややこしくて誠に申し訳ございません。。
(シロ) 2018/09/17(月) 16:53

 ということは、カンマに問題がありそうな...
 csvファイルをメモ帳で開いて、カンマの部分(前後の空白を含めた)を提示してください。
(seiya) 2018/09/17(月) 16:57

seiyaさん

test1,ttest1
668-0263 ,668-0263
〒 006-0815 ,〒 006-0815
319-1541 ,319-1541
635-0074 ,635-0074
799-1301 ,799-1301
277-0031,277-0031
130-0011,130-0011
359-1145,359-1145
699-0406,699-0406
981-0501,981-0501
193-0835,193-0835
193-0835,193-0835
193-0835,193-0835
731-0213,731-0213
720-0832,720-0832
960-0231,960-0231
511-0033,511-0033
511-0811,511-0068
511-0811,511-0068

前回もメモ帳で開いてお渡ししたので同じようになりますが
宜しいのでしょうか?

スペースを無くしたい列の数行だけで宜しいですか?
(シロ) 2018/09/17(月) 17:08


 では、Patternを以下に変えて試してください。

             .Pattern = "[  ]+(?=([," & Chr(50) & "]|$))"
(seiya) 2018/09/17(月) 17:18

 一括返還から今日単位での変換にしましたが、これで変化はありますか?

 Sub test()
     Dim a, e, x, y, txt As String, i As Long, ff As Long
     a = Application.GetOpenFilename("CSVFiles,*.csv", , , , True)
     If Not IsArray(a) Then Exit Sub
     For Each e In a
         x = Split(CreateObject("Scripting.FileSystemObject").OpenTextFile(e).ReadAll, vbNewLine)
         ff = FreeFile
         Open Replace(e, ".csv", "_Trimmed.csv") For Output As #ff
             For i = 0 To UBound(x)
                 x(i) = myTrim(x(i))
                 Print #ff, x(i)
              Next
         Close #ff
     Next
 End Sub

 Function myTrim(ByVal txt As String) As String
      With CreateObject("VBScript.RegExp")
          .Global = True
          .Pattern = "[  ]+(?=(,|$))"
          txt = .Replace(txt, "")
          .Pattern = "(^|,)[  ]+"
          myTrim = StrConv(.Replace(txt, "$1"), 8)
     End With
 End Function
(seiya) 2018/09/17(月) 17:45

seiyaさん

上記のコードですと、他の列で問題がおきました。
また、変更したい箇所のスペースは消されておりませんでした。
(シロ) 2018/09/17(月) 18:58


 200列、10万行で実行しましたが、此方では全て期待通りの結果が得られています。(時間はかかりますが)
 私には実際のデータを見せていただく以外に、原因は分りかねます。
(seiya) 2018/09/17(月) 20:13

少しは解りやすいかも。初心者には無理かなあ。

Sub test2()

    Const 列1 As Long = 44, 列2 As Long = 88    '変換列 実際の列-1 とすること
    Dim Oldfile, Oldfiles
    Dim Newfile As String
    Dim OutFF As Long, InFF As Long
    Dim lineBufs
    Dim bufs
    Dim i As Long

    Oldfiles = Application.GetOpenFilename(FileFilter:="CSV ファイル ,*.csv", FilterIndex:=1, Title:="CSVファイルを選択してください", MultiSelect:=True)
    If Not IsArray(Oldfiles) Then Exit Sub
    For Each Oldfile In Oldfiles
        InFF = FreeFile
        Open Oldfile For Input As #InFF
        lineBufs = Split(StrConv(InputB(LOF(InFF), InFF), vbUnicode), vbCrLf)
        For i = 1 To UBound(lineBufs)   '項目行をskip
            bufs = Split(lineBufs(i), ",")
            If UBound(bufs) >= 列1 Then bufs(列1) = 変換(bufs(列1))    '列1+1 変換
            If UBound(bufs) >= 列2 Then bufs(列2) = 変換(bufs(列2))    '列2+1 変換
            lineBufs(i) = Join(bufs, ",")
        Next
        Newfile = Replace(Oldfile, ".csv", "_new.csv")
        OutFF = FreeFile
        Open Newfile For Output As #OutFF
        Print #OutFF, Join(lineBufs, vbCrLf);
        Close
    Next
End Sub
'半角にしてから"〒"と" "を除去し、"ー"を"-"に変換
Function 変換(buf) As String
    変換 = Replace(Replace(Replace(StrConv(buf, vbNarrow), "〒", ""), " ", ""), "ー", "-")
End Function

(kazuo) 2018/09/17(月) 21:18


KAZUOさん

お時間頂き誠に有難うございます。

上記のコードで処理をしたところ、45列目の修正箇所は19つですが16つに減り、
89列目は修正箇所は5つですが4つに減りましたの。

スペースが無くっているのは文末の半角スペースでした。
メモ帳で開いてみましたが、同じように文末の半角スペースなのにスペースが消えていないのがある
状況です。

45列目だと、

170-0011 ,170-0011 ,
668-0263 ,668-0263 ,
〒 006-0815 ,〒 006-0815 ,
319-1541 ,319-1541 ,

 031-0823 , 031-0823 ,
890-0026 ,890-0026 ,
124-0006 ,124-0006 ,
635-0074 ,274-0074 ,
274-0074 ,519-3922 ,
519-3922 , 084-0903,
 084-0903,897-0031 ,
897-0031 ,799-1301 ,
799-1301 , 531-0071 ,
 531-0071 ,593-8312 ,
251-0057 ,350-1302 ,
251-0057 ,649-7121 ,
593-8312 ,,
350-1302 ,,
649-7121 ,,

このようにスペースありの物が減りました。
ご確認宜しくお願い致します。

(シロ) 2018/09/18(火) 09:28


必要物抽出作戦 ^^
あまり自信はありませんが。。。だめなら、ログ、取りましたので(1000件に一件で)
strchr.logをメモ帳で開いたのここにアップしてください。
他にもアドバイス、くださるかもです。 ^^;
m(__)m

Option Explicit
Sub main_planC_A()

    Dim Oldfile As String, Newfile As String, buf As String, newbuf As String
    Dim tmp, i&, myarray, k
    myarray = Array("44", "84")
    On Error Resume Next
    Kill "strchr.log"
    On Error GoTo 0
    Oldfile = Application.GetOpenFilename(FileFilter:="CSV ファイル ,*.csv", FilterIndex:=1, Title:="CSVファイルを選択してください", MultiSelect:=False)
    If VarType(Oldfile) = vbBoolean Then Exit Sub
    Newfile = Replace(Oldfile, ".csv", "new.csv")
    Open Newfile For Output As #1
        Open Oldfile For Input As #2
            Do Until EOF(2)
                Line Input #2, buf
                k = k + 1
                tmp = Split(buf, ",")
                For i = 0 To UBound(myarray)
                    tmp(myarray(i)) = str_chk(tmp(myarray(i)), k)
                Next
                newbuf = Join(tmp, ",")
                Print #1, newbuf
                DoEvents
            Loop
        Close #2
    Close #1
    MsgBox Newfile & "として保存しました。"
End Sub
Private Function str_chk(ByVal arg1 As String, ByVal w As Long) As String
    Dim i&, tmp, fn%
    fn = FreeFile
    If w Mod 1000 = 0 Then Open "strchr.log" For Append As fn
    For i = 1 To Len(arg1)
        If w Mod 1000 = 0 Then Print #fn, Asc(StrConv(Mid(arg1, i, 1), vbNarrow)) & ",";
        If Asc(StrConv(Mid(arg1, i, 1), vbNarrow)) > 32 Then
            tmp = tmp & StrConv(Mid(arg1, i, 1), vbNarrow)
        End If
    Next
    str_chk = tmp
    If w Mod 1000 = 0 Then Print #fn,: Close fn
End Function

(隠居じーさん) 2018/09/18(火) 10:44


隠居じーさん

お時間頂き誠に有難うございます。

デバックがでておりまして
tmp(myarray(i)) = str_chk(tmp(myarray(i)), k)
の箇所で

インデックスがが有効範囲にございません

というエラーでした。
(シロ) 2018/09/18(火) 11:04


あ!はい、見てみますね。。。しばし ご猶予を

(隠居じーさん) 2018/09/18(火) 11:27


え〜と確認ですが ^^
読込CSVファイルの列数と云いますか、【 , 】の数はいくつあるのでしょうか
テストでお使いの2列しか無い分だとエラーが出ます
少なくとも85列以上のCSVを読み込んでいただいていますでしょうか。

処理対象が45、85列目の情報(郵便番号がある列!)が前程です。

(隠居じーさん) 2018/09/18(火) 11:39


すみません きがつかず
以前、のやり取りの中で空白行(一行丸ごと空)があるのですね。
それと85列目ではなく89列目でしたね
今から、修正いたします。
^^;;;
m(__)m

(隠居じーさん) 2018/09/18(火) 12:00


隠居じーさん

列数ですが151ございます。

なん箇所かに空白もございます。
大変お手間をお掛け致しまして申し訳ございません。
(シロ) 2018/09/18(火) 12:02


 下記コードに置き換え後、
お試しを ^^;

 Option Explicit
Sub main_planC_A()
    Dim Oldfile As String, Newfile As String, buf As String, newbuf As String
    Dim tmp, i&, myarray, k
    myarray = Array("44", "88")
    On Error Resume Next
    Kill "strchr.log"
    On Error GoTo 0
    Oldfile = Application.GetOpenFilename(FileFilter:="CSV ファイル ,*.csv", FilterIndex:=1, Title:="CSVファイルを選択してください", MultiSelect:=False)
    If VarType(Oldfile) = vbBoolean Then Exit Sub
    Newfile = Replace(Oldfile, ".csv", "new.csv")
    Open Newfile For Output As #1
        Open Oldfile For Input As #2
            Open "strchr.log" For Append As #3
                Do Until EOF(2)
                    Line Input #2, buf
                    If buf <> "" Then
                        k = k + 1
                        tmp = Split(buf, ",")
                        For i = 0 To UBound(myarray)
                            tmp(myarray(i)) = str_chk(tmp(myarray(i)), k)
                        Next
                        newbuf = Join(tmp, ",")
                        Print #1, newbuf
                        DoEvents
                    End If
                Loop
            Close #3
        Close #2
    Close #1
    MsgBox Newfile & "として保存しました。"
End Sub
Private Function str_chk(ByVal arg1 As String, ByVal w As Long) As String
    Dim i&, tmp
    For i = 1 To Len(arg1)
        If w Mod 1000 = 0 Then Print #3, Asc(StrConv(Mid(arg1, i, 1), vbNarrow)) & ",";
        If Asc(StrConv(Mid(arg1, i, 1), vbNarrow)) > 32 Then
            tmp = tmp & StrConv(Mid(arg1, i, 1), vbNarrow)
        End If
    Next
    str_chk = tmp
    If w Mod 1000 = 0 Then Print #3,
End Function
でわ
(隠居じーさん) 2018/09/18(火) 12:20

隠居じーさん

同じ箇所で同じエラーがでました(><)
(シロ) 2018/09/18(火) 13:26


え^^;そぉなんですね。。。
ちょっとお待ちくださいね、そのへんに何か原因があるやもしれませんね

(隠居じーさん) 2018/09/18(火) 14:35


お待たせいたしました。
下記コードに差し換え後、実行していただきますと、同フォルダ内に
strchr.log
というのが出来ています
最初の行初めの数値がエラー行です。その行の列数を調べてください。
いままで成功しなかった行ではないでしょうか
それと、strchr.logの
中身をここに貼り付けてみてくださいますか。

 Option Explicit
Sub main_planC_A()
    Dim Oldfile As String, Newfile As String, buf As String, newbuf As String
    Dim tmp, i&, myarray, k
    myarray = Array("44", "88")
    On Error Resume Next
    Kill "strchr.log"
    On Error GoTo 0
    Oldfile = Application.GetOpenFilename(FileFilter:="CSV ファイル ,*.csv", FilterIndex:=1, Title:="CSVファイルを選択してください", MultiSelect:=False)
    If VarType(Oldfile) = vbBoolean Then Exit Sub
    Newfile = Replace(Oldfile, ".csv", "new.csv")
    Open Newfile For Output As #1
        Open Oldfile For Input As #2
            Open "strchr.log" For Append As #3
                Do Until EOF(2)
                    Line Input #2, buf
                    If buf <> "" Then
                        k = k + 1
                        On Error GoTo err
                        tmp = Split(buf, ",")
                        For i = 0 To UBound(myarray)
                            tmp(myarray(i)) = str_chk(tmp(myarray(i)), k)
                        Next
                        newbuf = Join(tmp, ",")
                        Print #1, newbuf
stp1:
                        DoEvents
                    End If
                Loop
            Close #3
        Close #2
    Close #1
    MsgBox Newfile & "として保存しました。"
    Exit Sub
err:
    Print #3, k & "," & UBound(tmp)
    On Error GoTo 0
    Resume stp1
End Sub
Private Function str_chk(ByVal arg1 As String, ByVal w As Long) As String
    Dim i&, tmp
    For i = 1 To Len(arg1)
        'If w Mod 1000 = 0 Then Print #3, Asc(StrConv(Mid(arg1, i, 1), vbNarrow)) & ",";
        If Asc(StrConv(Mid(arg1, i, 1), vbNarrow)) > 32 Then
            tmp = tmp & StrConv(Mid(arg1, i, 1), vbNarrow)
        End If
    Next
    str_chk = tmp
    'If w Mod 1000 = 0 Then Print #3,
End Function

(隠居じーさん) 2018/09/18(火) 14:57


隠居じーさん

strchr.log ファイルがでました!
全部貼り付けると多いので90番目までにしておきます!

2,14
4,14
5,0
7,14
8,0
12,14
13,0
15,17
16,14
17,0
19,17
20,14
22,17
23,14
24,0
26,17
27,14
29,14
30,0
32,14
34,14
36,14
38,14
40,17
41,14
42,0
44,14
45,0
46,0
48,14
50,14
54,14
55,0
58,14
60,14
61,0
64,14
66,14
68,14
69,0
70,0
72,14
74,14
76,14
77,0
79,14
80,0
82,14
83,0
87,14
89,14
90,0

(シロ) 2018/09/18(火) 15:13


C案で話が進んでるようなので、そちらは皆さんにお任せでB案の一例です。
気が向いたときの研究材料としてお使い下さい。

    Sub B案()
        Dim 対象フォルダ As String
        Dim ファイル名 As String
        Dim MyCOL As Variant

        Stop

        'ダイアログボックスでユーザーに対象フォルダを指定させる
        With Application.FileDialog(msoFileDialogFolderPicker)
            If .Show = True Then
                対象フォルダ = .SelectedItems(1)
            Else
                MsgBox prompt:="フォルダが正しく指定されませんでした。" & vbCrLf & "プログラムを終了します", Title:="エラー"
                Exit Sub
            End If
        End With

        'フォルダ内のCSVファイルを探す
            '【ヒント:DIR関数】

        'B案でループ処理
        Do Until ファイル名 = ""
            With Worksheets("作業用")
                .Cells.Clear

                'テキストデータの取込
                With .QueryTables.Add _
                    (Connection:="TEXT;" & 対象フォルダ & "\" & ファイル名, Destination:=.Range("A1"))

                    .TextFileParseType = xlDelimited ' 区切り文字の形式
                    .TextFileCommaDelimiter = True   ' カンマ区切り
                    .TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, _
                                                     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, _
                                                     1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, _
                                                     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, _
                                                     1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, _
                                                     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, _
                                                     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, _
                                                     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) '151項目中、45、85項目を文字列として取込(他は標準)
                    .RefreshStyle = xlOverwriteCells ' セルに上書き
                    .Refresh                         ' データを表示
                    .Delete                          ' CSV との接続を解除
                End With

                '置換処理
                For Each MyCOL In Array(45, 85)
                    .Columns(MyCOL).Replace What:=" ", Replacement:="", LookAt:=xlPart
                    .Columns(MyCOL).Replace What:="−", Replacement:="-", LookAt:=xlPart
                Next MyCOL

            End With

            '新規ブックにシートごとコピーしてCSV形式で(上書き)保存
            With Workbooks.Add
                ThisWorkbook.Worksheets("作業用").Copy Before:=.Worksheets(1)

                Application.DisplayAlerts = False
                .SaveAs Filename:=対象フォルダ & "\" & ファイル名, FileFormat:=xlCSV
                .Close
                Application.DisplayAlerts = True
            End With

            '次のcsvファイルを探す
            ファイル名 = Dir()
        Loop

    End Sub

(もこな2) 2018/09/18(火) 15:39


はい、ありがとうございます。
誠に申し上げづらいのですが。。。
左は空白行は数に入っていないと思いますが概ねエラーだった行番で、その右はコンマで区切られた
列の数を表しています。すーごぉく不規則で、85列目、89列目が存在しないため処理を実行出来て
おりません。諸先輩の方は列数にとらわれない一括処理をしておられたようですね。
わたしのコードの書き方が間違っているのかもしれません。
お役に立てず申し訳ありません。
私のスキルを越える処理が必要なようです。

郵便番号記号(〒)は全ての郵便番号についているのでしょうか。(目印)
一度、エクセルに取込、整理されるのも良いかもしれませんね。

また良い、案が浮かびましたらアップさせていただきます。
m(__)m

(隠居じーさん) 2018/09/18(火) 16:20


 シロさん
 45と89列目のみを対象。
 これでダメだったら、お手上げです。

 Option Explicit
 Private RegX As Object

 Sub test()
     Dim a, e, x, y, txt As String, i As Long, ffIn As Long, ffOut As Long
     a = Application.GetOpenFilename("CSVFiles,*.csv", , , , True)
     If Not IsArray(a) Then Exit Sub
     Set RegX = CreateObject("VBScript.RegExp")
     For Each e In a
         ffIn = FreeFile
         Open e For Input As #ffIn
            ffOut = FreeFile
            Open Replace(e, ".csv", "_Trimmed.csv") For Output As #ffOut
                Do Until EOF(ffIn)
                    Line Input #ffIn, txt
                    txt = myTrim(txt)
                    Print #ffOut, myTrim(txt)
                Loop
            Close #ffOut
         Close #ffIn
     Next
     Set RegX = Nothing
 End Sub

 Function myTrim(ByVal txt As String) As String
     Dim x, e
     myTrim = txt
     If myTrim = "" Then Exit Function
     x = Split(txt, ",")
     If UBound(x) > 87 Then
        With RegX
            .Global = True
            .Pattern = "^[  \u00A0]+|[  \u00A0]+$"
            For Each e In Array(44, 88)
                x(e) = StrConv(.Replace(x(e), ""), 8)
            Next
        End With
     End If
     myTrim = Join(x, ",")
 End Function
(seiya) 2018/09/18(火) 17:19

どこかの列にダブルコーテーションで囲まれた , が有ると言うことですね。
例: "hogehoge,ふがふが"
やはり、一旦excelに取り込むしかないのかな。

(kazuo) 2018/09/18(火) 19:39


2018/09/18(火) 15:39 投稿のコードを一部修正。

ついでに、途中追ってなかったのでよくわからないですけど、

 45列目が「注文者郵便番号1」 
 85列目が「送付先郵便番号1」

っていうのがそもそも固定じゃないっぽいんでしょうか?
(もこな2) 2018/09/19(水) 07:36


たくさんのご意見誠に有難うございます。

一行目の項目名は固定なので、
45と89列目の名称も固定となります。

seiyaさんのコードで試しましたがスペースが消えませんでした。。

他の列の何かがじゃましているのでしょうか。。
(シロ) 2018/09/19(水) 09:38


 提示されたデータにはダブルクォーテーションがありませんが、もしあるのなら話は変わってきます。
 以下で試してください。

 Option Explicit
 Private RegX As Object

 Sub test()
     Dim a, e, x, y, txt As String, i As Long, ffIn As Long, ffOut As Long
     a = Application.GetOpenFilename("CSVFiles,*.csv", , , , True)
     If Not IsArray(a) Then Exit Sub
     Set RegX = CreateObject("VBScript.RegExp")
     For Each e In a
         ffIn = FreeFile
         Open e For Input As #ffIn
            ffOut = FreeFile
            Open Replace(e, ".csv", "_Trimmed.csv") For Output As #ffOut
                Do Until EOF(ffIn)
                    Line Input #ffIn, txt
                    txt = myTrim(txt)
                    Print #ffOut, txt
                Loop
            Close #ffOut
         Close #ffIn
     Next
     Set RegX = Nothing
 End Sub

 Function myTrim(ByVal txt As String) As String
    With RegX
        .Global = True
        .Pattern = "((^|,)""?)[  \u00A0]+|[  \u00A0]+("")?(?=,)"
        myTrim = .Replace(txt, "$1$3")
        MsgBox myTrim
    End With
 End Function
(seiya) 2018/09/19(水) 10:32

seiyaさん

上記のコードで実行するとmsgboxでメッセージがでてきますが
okまたは閉じるを押しても次のメッセージがでてきてきりがないので
強制終了致しました。

ご相談する際にcsvデータに空白があるかないかでコードが変わっておりましたが
151列の中にこういうデータはあるとお伝えすべき内容はございますでしょうか??

お手数をお掛け致しまして申し訳ございせん。
(シロ) 2018/09/19(水) 11:11


 >        MsgBox myTrim
 これ削除して下さい。
 私の確認のためのものでした...
(seiya) 2018/09/19(水) 11:16

seiyaさん

上記のコードで45と89列目の空白がなくなりました!
有難うございます!

こちら一個ファイルの処理をしておりますが、
処理したいファイルをフォルダにまとめておりまして、
そちらの順に処理するコードを足すことはできますでしょうか?

デスクトップにフォルダは作成しております。
(シロ) 2018/09/19(水) 14:44


 只今外出中ですので後ほど。
 あとは簡単です。
(seiya) 2018/09/19(水) 15:20

 確認しますが、このコードは列に関わりなく行頭・行末そしてカンマの前後
 (ダブルクォーテーションの有無に関わらず)の空白を削除します。

 ですので、各列をトリムするのと同時に、列データの中にコンマが存在する場合にも
 もしその前後に空白がある場合は削除しています。

 もしそれがまずいのなら、もう一工夫必要です。

 Option Explicit

 Private RegX As Object

 Sub test()
     Dim myDir As String, fn As String, txt As String, ffIn As Long, ffOut As Long
     With Application.FileDialog(msoFileDialogFolderPicker)
        .InitialFileName = CreateObject("WScript.Shell").SpecialFolders("desktop")
        If .Show Then myDir = .SelectedItems(1) & "\"
     End With
     If myDir = "" Then Exit Sub
     fn = Dir(myDir & "*.csv")
     Set RegX = CreateObject("VBScript.RegExp")
     Do While fn <> ""
         ffIn = FreeFile
         Open myDir & fn For Input As #ffIn
            ffOut = FreeFile
            Open myDir & Replace(fn, ".csv", "_Trimmed.csv") For Output As #ffOut
                Do Until EOF(ffIn)
                    Line Input #ffIn, txt
                    txt = myTrim(txt)
                    Print #ffOut, txt
                Loop
            Close #ffOut
         Close #ffIn
         fn = Dir
     Loop
     Set RegX = Nothing
 End Sub

 Function myTrim(ByVal txt As String) As String
    With RegX
        .Global = True
        .Pattern = "((^|,)""?)[  \u00A0]+|[  \u00A0]+("")?(?=(,|$))"
        myTrim = .Replace(txt, "$1$3")
    End With
 End Function

(seiya) 2018/09/19(水) 16:32


seiyaさん

ご質問です。

このコードは列に関わりなく行頭・行末そしてカンマの前後

 (ダブルクォーテーションの有無に関わらず)の空白を削除します。
 ですので、各列をトリムするのと同時に、列データの中にコンマが存在する場合にも
 もしその前後に空白がある場合は削除しています。

↑こちらの内容ですが、どういったときに困るかピンときておりません。。
例えば、2018-09-19 17:00
こちらが 2018-09-1917:00
と真ん中のスペースが消えてしまうと年月日がおかしくなりますが、trimだけならスペースは消えません。

例があると助かります(><)
(シロ) 2018/09/19(水) 17:08


 例えばエクセルでいうところのA列(どの列でも)のデータに
 123, xyz, 567
 のような、列内のデータにカンマで区切られたデータがある場合です。
 123,xyz,567
 に変換してしまう、ということです。
(seiya) 2018/09/19(水) 17:15

seiyaさん

解説誠に有難うございます!

セル内にコンマ区切り後のスペースはございませんので
大丈夫です!

データ量が多いとそういったことを理解しておかないと
いけないのですね。

長々とご相談にのっていただき感謝でいっぱいです。
誠に有難うございます。

お時間頂けたらですが、上記のコードを理解していくうえで
ヒントを頂きたいです。

この行でなにをしているかというのを学ぶ上でポイントとなる
関数など。。

ご無理な場合はもちろん大丈夫です。

マクロのすばらしさを体験できて本当に感謝です!
(シロ) 2018/09/19(水) 17:25


 簡単に言うと

 選択されたフォルダ内の全csvファイルをシーケンシャルモードで開き、一行づつ読み込む。
 同時に同じくシーケンシャルモードで書き込み用ファイルを開き書き込む。
 その際、正規表現を使用して各列の文頭・文末、及びカンマ周辺の空白を削除。

 といったところです。
 分らない単語等があれば、ネット等で調べてください。
 それでも不明な点があったら、どこが分らないのか質問してください。
(seiya) 2018/09/19(水) 18:17

コメント返信:

[ 一覧(最新更新順) ]


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