[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『大量のcsvからスペースをとりたい』(シロ)
ご相談なのですが、
何万件と入ったcsvデータが複数ございまして、
45列目と85列目が郵便番号なのですが、
例)999-999 ←スペース
のスペースを無くしたいのと
999ー999
と全角のハイフンを半角のハイフンに修正する
のにマクロなどで時間短縮できないでしょうか?
直したいのは45列目の注文者郵便番号1
と85列目の送付先郵便番号1
です。
宜しくお願い致します。
< 使用 Excel:Excel2016、使用 OS:Windows10 >
プランB
CSVをテキストファイルとしてシート上にインポートして、編集後、作業結果のシートをCSV形式で保存する
プランC
マクロ上でテキストデータをメモリ上に直接読み込み、編集後、ファイルに出力したい。
(ブック、シートは関係ない)
のどれなんでしょうか?
ちなみに、比較したことないので、どれが良いかはわからないですけど、いろいろ勉強になりそうなのはB案でしょうか・・
お手軽ならA案ですけど、「0123」→「123」や「1/4」→「1月4日」のようにExcel君が”標準”と思っている形式に勝手に変更されたりといった弊害が出る可能性があります。
(もこな2) 2018/09/14(金) 15:08
ご提案頂いた
プランbでお願いできますでしょうか?
プランaはブックとして開くと確かに弊害がでそうですね。。
宜しくお願い致します。
(シロ) 2018/09/14(金) 15:31
プランBでいくならいくで、どこまで自分でできるのか(わかるのか)、作りかけでいいので見せてもらわないと話がすすみません。
(もこな2) 2018/09/14(金) 16:38
あまりに量が多いためこちらにヘルプをだしてみました。
他にもしご回答いただける方がいらっしゃればお力添えをお願い致します。
(シロ) 2018/09/14(金) 16:46
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
???さん、初めましてなのにその口の利き方はなんですか?
他の質問掲示板でも随分辛口みたいですが。
ただ文句いいたいだけならそもそもここにこなければいい。
(シロ) 2018/09/14(金) 18:22
あと、複数のCSVと言ってるだけで、実際にはいくつあるのかわかりませんが、100ファイルとかあったら、A案もB案も
(1)開く(インポートする) (2)マクロなり手動なりで作業する (3)保存(して閉じる)
を100回繰り返すことになるので、おっしゃる通り一通りの作業をマクロ化したほうがよいとは思います。
その場合、開きたいCSVファイルのフルパス(少なくともファイル名)を取得する必要がでてきますが、
Excel ファイル一覧 なんてキーワードでネット検索すると手ごろな情報があるとおもいますので当たってみてください。
(あくまで、自分でマクロを作ろうとした場合です。)
(もこな2) 2018/09/14(金) 18:29
マクロを自分で作ろうとしております。
量が多いので一つ一つ置換するよりマクロ化したほうが良いと当方も思いました。
プラン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
(隠居じーさん) 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
seiyaさん
いつもありがとうございます
m(__)m
(隠居じーさん) 2018/09/14(金) 20:47
csvのデータは150列ほどございまして、どこかの列で空白があるかもしれせん。
明日以降になりますが、実施してみます!
(シロ) 2018/09/14(金) 20:57
メモリ上で処理するから実行速度は速いでしょうけど、シート上で何か処理をするわけではないので、ステップ実行しても目視確認できませんし、”マクロの記録”も使えません。
また。???さんのコメントを再度よく見てください。
めちゃくちゃ正攻法書いてありますよ。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
ご質問です。
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
早速のご回答誠に有難うございます。
If = buf <> "" Then
の箇所が構文エラーとなります。
end if
もございますし、どこがおかしいのでしょうか・・
(シロ) 2018/09/15(土) 15:43
おっと、= を削除して下さい。 If buf <> "" Then (seiya) 2018/09/15(土) 15:49
=を削除でエラー回避できました!
新たに
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
as以降の省略理解致しました。
有難うございます。
ご報告ですがエラーはでなくなりましたが、
テストで処理前と処理後の45と89列目の
スペースを確認致しましたが、なくなっておりませんでした。
エラーはでていないので、なにかプログラムが足りないのでしょうか。。
(シロ) 2018/09/15(土) 20:17
そのcsvをエクセルで開いたとき、Trim関数で除去できるものですか?
出来たらcsvの対象スペースを削除したい数行を (既存のデータは適当に変更してもスペースは変更せずに) 提示してもらうと分かりやすいと思います。 (seiya) 2018/09/15(土) 20:28
(γ) 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さん
処理したい列二つだけを抽出し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
上記のコードに修正すると
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
引数は省略できません
というエラーが
buf = myTrim
の箇所ででております。
こちらの対処方法が分かりかねます。
宜しくお願い致します。
(シロ) 2018/09/17(月) 13:12
失礼しました...
そこは
buf = myTrim(buff)
にしてください。 (seiya) 2018/09/17(月) 13:16
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
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
上記のコードでも151列のデータではスペースは消えませんでした。
testで適当に20列ぐらいに減らして実行すると
なぜかスペースは消えておりました。
掲示板なので151列あるデータを見て頂きたいですが、すべてはご提示できません。。
(シロ) 2018/09/17(月) 15:18
>上記のコードでも151列のデータではスペースは消えませんでした。 全列、全く消えないのですか?それとも消える列と消えない列があるのですか?
(seiya) 2018/09/17(月) 15:32
最初に申し上げました、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
上記の処理したい番号は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
上記のコードでしたらスペースは消えておりました!
他の列も全てです!
(シロ) 2018/09/17(月) 16:22
問題はカンマの前後のスペースですよね。
> .Pattern = "[ ]+" を .Pattern = "[ ]+(?=(,|$))" にして試して下さい。 カンマの前のスペースだけを除去しますので確認してください。
(seiya) 2018/09/17(月) 16:38
こちらのコード
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
ということは、カンマに問題がありそうな... csvファイルをメモ帳で開いて、カンマの部分(前後の空白を含めた)を提示してください。 (seiya) 2018/09/17(月) 16:57
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
上記のコードですと、他の列で問題がおきました。
また、変更したい箇所のスペースは消されておりませんでした。
(シロ) 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
お時間頂き誠に有難うございます。
上記のコードで処理をしたところ、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
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
(隠居じーさん) 2018/09/18(火) 11:39
(隠居じーさん) 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
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
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
郵便番号記号(〒)は全ての郵便番号についているのでしょうか。(目印)
一度、エクセルに取込、整理されるのも良いかもしれませんね。
また良い、案が浮かびましたらアップさせていただきます。
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
(kazuo) 2018/09/18(火) 19: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
上記のコードで実行するとmsgboxでメッセージがでてきますが
okまたは閉じるを押しても次のメッセージがでてきてきりがないので
強制終了致しました。
ご相談する際にcsvデータに空白があるかないかでコードが変わっておりましたが
151列の中にこういうデータはあるとお伝えすべき内容はございますでしょうか??
お手数をお掛け致しまして申し訳ございせん。
(シロ) 2018/09/19(水) 11:11
> MsgBox myTrim これ削除して下さい。 私の確認のためのものでした... (seiya) 2018/09/19(水) 11:16
上記のコードで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
ご質問です。
このコードは列に関わりなく行頭・行末そしてカンマの前後
(ダブルクォーテーションの有無に関わらず)の空白を削除します。 ですので、各列をトリムするのと同時に、列データの中にコンマが存在する場合にも もしその前後に空白がある場合は削除しています。
↑こちらの内容ですが、どういったときに困るかピンときておりません。。
例えば、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
解説誠に有難うございます!
セル内にコンマ区切り後のスペースはございませんので
大丈夫です!
データ量が多いとそういったことを理解しておかないと
いけないのですね。
長々とご相談にのっていただき感謝でいっぱいです。
誠に有難うございます。
お時間頂けたらですが、上記のコードを理解していくうえで
ヒントを頂きたいです。
この行でなにをしているかというのを学ぶ上でポイントとなる
関数など。。
ご無理な場合はもちろん大丈夫です。
マクロのすばらしさを体験できて本当に感謝です!
(シロ) 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.