通常、エクセルでテキストファイルを読み込もうとすると、ウイザードが立ち上がりそれを終えると読み込めます。
私はこのウイザードで、「カンマやタブなどの区切り文字で…」を選択し、次へ。次の画面で「タブ」と「スペース」にチェックを入れます。なお、スペースにチェックを入れると、自動的に「連続した区切り文字は1文字として扱う」にチェックが入ります。
そして次へ→、完了としてテキストを読み込んでいます。
このたび、この操作が面倒なので、マクロで実行しようといろいろ調べていたら、自分のやりたいことと一番近いサンプルマクロを見つけました。以下です。
http://www.bekkoame.ne.jp/~poetlabo/COMP/Excel/V …
このマクロをそのまま書いて実行すると、区切り文字を指定でき、読み込めます。
ただし、このままだと区切り文字を1つしか指定できません。
先ほど書いたように、今回は「スペース」「タブ」で区切って開きたいのですが、上記のサンプルプログラムをどう改変すればよいのでしょうか?
No.7ベストアンサー
- 回答日時:
こんにちは。
別に元のコード自体を評価するというような気持ちではありませんが、このコードは、シーケンシャルファイル用(拡張子は、.dat)にも適用できるマクロです。それで、問題は発生はしないけれども、全体的に、インポートは遅いはずです。
それと、誰もご指摘にならないようですが、元のサンプルのコードは、Excel97 用です。
Excel2000以上なら、テキストラインで、このようなことは必要ないはずです。
Call ReadLine(CurTxt, DeLimiter, rn)
Split 関数で十分なはずです。ただし、デリミタは、一つに限るので、その前に、Replace 関数で、置換しておく必要があります。
今風の書き方ではないし、プロシージャが分散しすぎて読みにくいように思います。新たに、書き直したほうがよい様な気もしてくるのですが。
記録マクロに関して、
>どうも思うのと違うため、今のところ保留にしています。
>「読み込み」と「開く」は違うみたいで、手動でやっているのと同じ結果にはなるのですが、新しいファイルが開いて、そこにテキストファイルが開かれたり…。
それは、インポートの方法が違っているからです。これは、VBAのオブジェクトで言えば、QueryTable といいますが、ワークシートでは、[外部データの取り込み]のことを指します。オプション自体は、複雑なこともありますので、記録マクロを利用するのが一番です。なお、Tab と Comma 共存の場合は、QueryTable が優れています。
VBA入門レベルでも、記録マクロと組み合わせれば可能かと思います。というか、よほど、インポート間で加工しなければ、このまま使えると思います。
例:
Sub TestMacro1()
Dim Fname As Variant
On Error Resume Next
ActiveSheet.QueryTables(1).Delete 'QueryTableがあったら削除
On Error GoTo 0
Fname = Application.GetOpenFilename( _
"テキストファイル (*.txt; *.csv),*.txt;*.csv", 1, "OpenTextFile")
If VarType(Fname) = vbBoolean Then Exit Sub
'-------------------細かいオプションは、記録マクロから取り出してください。---
With ActiveSheet.QueryTables.Add( _
Connection:="TEXT;" & Fname, _
Destination:=Cells(1, 1))
.AdjustColumnWidth = False '列幅の自動調整
.TextFileCommaDelimiter = True 'カンマ切り
.Refresh BackgroundQuery:=False 'バックグラウンドの再入力(一回きり)
.TextFileTabDelimiter = True 'タブデリミタあり
End With
'-------------------
ActiveSheet.QueryTables(1).Delete
End Sub
回答ありがとうございます。
とりあえず教えてくださったサンプルプログラムをそのまま実行してみました。うまく読み込めましたが、やはり区切り方が不十分だったので、以下のことを試してみました。
まず、
.TextFileTabDelimiter = True 'タブデリミタあり
のあとに、
.TextFileSpaceDelimiter = Trueを加えて実行。
なぜか加えた一文に反応してくれてないようなので、この一文の位置を変更してみました。(「.AdjustColumnWidth = False '列幅の自動調整
」の文の次など)そしたら反応するようになってくれましたが、今度は区切り文字が多すぎて失敗。
次に「マクロの記録」を参考にして、
.TextFileConsecutiveDelimiter = True を加えて実行。
これもなぜか反応してくれてないようなので、位置を変えて再び実行したところ、見事希望通りの結果になってくれました。
なぜ書いた記述に反応してくれないかを確かめるため、もう一度まっさらな状態から教えていただいたプログラムを書き、
.TextFileTabDelimiter = True 'タブデリミタありの次に
.TextFileSpaceDelimiter = True
.TextFileConsecutiveDelimiter = True
の2文を加えて実行してみました。が、やはり反応してくれません。
次に、同様に、この2文の記述位置を変えて実行→見事反応して、期待通りの結果になりました。
位置をずらさないと反応してくれない理由はわかりませんが、ひとまず期待通りの結果を出せることができました。実行速度も格段に速くなって(一瞬の速さ)満足です。
回答ありがとうございました。
No.8
- 回答日時:
こんにちは。
#7です。
ある程度の確信はあったのですが、うまくいって、よかったです。
>やはり区切り方が不十分だったので、以下のことを試してみました。
>これもなぜか反応してくれてないようなので、位置を変えて再び実行したところ、見事希望通りの結果になってくれました。
一応、弁解されてください。実は、こういうところって、あまり考えないで、本当は、記録マクロのその設定部分を、全部貼り付けていただいたほうがよいようです。細かい、オプションまでは、見切れていないのです。まして、私自身、順番とかあるのは知りませんでした。
それと、ちょっと気になったことですが、
以下は、今、試してみましたが、シートの使いまわしするような場合に、既にデータがあったりすると、誤動作があるようです。それに、QueryTable(クエリテーブル)は、インターネットからデータを取るようなこと以外は、通常は無用の長物なので、このように変えたほうがよいようです。
>On Error Resume Next
> ActiveSheet.QueryTables(1).Delete 'QueryTableがあったら削除
>On Error GoTo 0
↓
Dim qt As Object
ActiveSheet.UsedRange.ClearContents '一応データだけのクリア(書式も含めるとClear)
For Each qt In ActiveSheet.QueryTables
qt.Delete 'QueryTableがあったら削除
Next
No.6
- 回答日時:
掲出のプログラムの改良ではないが、下記の方が判りやすい・簡単と思う。
デリミタは普通カンマ、スペース、タブなどが多いようですが
(1)大げさですが、対話式に利用者にデリミタを選択させるのか
(2)プログラムの中にどれか決めてしまって、1つをセットするのか
(3)指定は何もしないようにしたいのか
どれですか。質問では明確ではない。
ーー
それと区切り文字はファイル1つを作られるときは、普通は1種と思いますが、
>「スペース」「タブ」で区切って開きたいのですが、
とはスペース出現でも区切り、タブ出現でも区切るようにしたいということですか。
(A)1つのファイルの場合か
(B)色々な別ファイルの場合にデリミタがバラバラのこと
なのか。
下記VBAは(A)でやっているが、(B)でも1つのプログラムで対応すると思う。
ーー
(3)とすると
エクセルVBAの課題らしいので、エクセルVBAらしく、エクセルにあるデーター区切り位置の機能を使いました。
・レコードを読んでA列にセット
・そのA列1行分データを、データー区切り位置の機能で各列に分離
の作業を(自動で)を行うと
Sub test01()
i = 1
Open "C:\Documents and Settings\xxx\My Documents\text14.txt" For Input As #1
While Not EOF(1)
Line Input #1, a
Cells(i, "A") = a
'---
Cells(i, "A").TextToColumns Destination:=Cells(i, "A"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=True, Tab:=True, _
Semicolon:=False, Comma:=True, Space:=True, Other:=False
'---
i = i + 1
Wend
Close #1
End Sub
ーーー
上記はTab:=True,以下セミコロン、カンマ、スペースが指定されていますが、これらは
1つの文字列の中において、OR条件的に働いて、分離してくれることが確認できました。
もっと種類を増やしたければ、区切り位置の操作で「その他」に文字を指定してマクロの記録をとってどうなるか、調べてコードに追加してください。
そうすれば実行時にはデリミタの種類をユーザーが指定する必要はありません。
ファイル名は都度指定できるよう改良のこと。
ーーーー
途中の’--から’--まではマクロの記録をとって一部手直しをしたものを挿入した。
ーーーー
テスト
例データ
メモ帳で
aa,bbb cd(T)df
xxx yyyy,zz vv
ww(T)ff(T)rr,tt
(T)mm hh,dd
(T)はTABコードが入っている例を作りました。
レコード(およびファイル)内でタブ、カンマ、スペースの3種混合です。
-----
上記プログラム実行結果
A列 B列 C列 D列
aabbbcddf
xxxyyyyzzvv
wwffrrtt
mmhhdd
とうまく行くようです。
>(1)大げさですが、対話式に利用者にデリミタを選択させるのか
>(2)プログラムの中にどれか決めてしまって、1つをセットするのか
>(3)指定は何もしないようにしたいのか
今回、読み込ませるテキストファイル内の記述形式は決まっているので、対話式に選択させる必要もなく、決まりきった区切り文字で区切ってくれればいいです。今回はスペースとタブ(ただし、連続した区切り文字は1文字として扱う)ということです。
しかし、今後のプログラムで必要となってくると思うので、対話式で選択もぜひマスターしたい事項でもあります。
>とはスペース出現でも区切り、タブ出現でも区切るようにしたいということですか。
よくわかりませんが、通常のテキストファイルの開き方で開いたときと同じ結果になってくれればよかったのです。今回、ウイザードで「タブ」と「スペース」(それから自動でチェックが入る「連続した区切り文字は1文字…」)にチェックを入れて開いたらうまく開いてくれていたので、単純に「タブとスペース」と質問文には書いていたまでです。
プログラム作成のヒントありがとうございました。いろいろ試してみたいと思います。
No.5
- 回答日時:
こんなのではダメでしょうか?外していたらすみません。
Sub test()
Dim srcFileName As String
srcFileName = "C:\Documents and Settings\?????\My Documents\hoge.txt"
'ここは自動記録したコードを、テキストファイル名だけ変数で与えるように改変
Workbooks.OpenText Filename:=srcFileName, StartRow:= _
1, DataType:=xlDelimited, TextQualifier:=xlDoubleQuote, _
ConsecutiveDelimiter:=True, Tab:=True, Semicolon:=False, Comma:=False, _
Space:=True, Other:=False
'開いたテキストファイルのシートを、マクロを記述してあるブックに移動
ActiveSheet.Move Before:=ThisWorkbook.Sheets(1)
End Sub
No.4
- 回答日時:
Sub ReadLine(CurTxt As String, DeLimiter As String, rn As Integer)
Dim StrStart As Integer, StrEnd As Integer
Dim StrArray() As String, cn As Integer
StrStart = 1
(以下略)
これを
Sub ReadLine(CurTxt As String, DeLimiter As String, rn As Integer)
Dim StrStart As Integer, StrEnd As Integer
Dim StrArray() As String, cn As Integer
CurTxt = Replace(CurTxt, " ", DeLimiter)
StrStart = 1
(以下略)
と一文追記しただけですね。
Replace関数は、おっしゃっている通りでOKです。厳密には、
CurTxt変数(読み込んだ1行分の内容)の中の" "(半角スペースです)をDeLimiter変数の中身に置き換えた結果をCurTxtに代入
と言う事になります。
回答ありがとうございます。
一文追加してみましたが、まだ思うようになりません。
しかし、こういう方法もあると大変参考になりました。
いろいろ試してみたいと思います。
No.3
- 回答日時:
タブは、「Chr(9)」ですよ。
自分なら、サブルーチン「ReadLine」中で
初めに、スペースを分割文字列に置換しちゃうかな?
Dim で定義した直後に、
CurTxt = Replace(CurTxt, " ", DeLimiter)
こうかな?
こうすれば、その後の処理でスペースの部分も分割文字列として扱われる気がします。
回答ありがとうございます。
おっしゃっていることを確認させてください。
Sub ReadLine(CurTxt As String, DeLimiter As String, rn As Integer)
Dim StrStart As Integer, StrEnd As Integer
Dim StrArray() As String, cn As Integer
サブルーチン「ReadLine」とは上記の部分から始まるところでいいですか?
「ReadLine」の中とはReadLineサブルーチンのどの変なのでしょうか。
>Dim で定義した直後に
何を定義するのでしょう。新しい変数??
CurTxt = Replace(CurTxt, " ", DeLimiter)
この意味はCurTxtの中の""(つまりスペースのことですよね)をDeLimiter変数の中身に置き換えるという意味でよろしいですか?
うーむ、まだまだぜんぜん理解が足りないです…。
No.2
- 回答日時:
いつもやっている作業をマクロの自動記録した事ありませんか?
そこから改良してみても良いのかと思いますけど。
もちろんそれはいの一番に試しました。
が、どうも思うのと違うため、今のところ保留にしています。
「読み込み」と「開く」は違うみたいで、手動でやっているのと同じ結果にはなるのですが、新しいファイルが開いて、そこにテキストファイルが開かれたり…。手動のときはしょうがないので、それをコピーして、目的のエクセルのファイルに貼り付けてました。
今回発見したプログラムは実行したエクセルファイルにちゃんと読み込んでくれますし、非常に使い勝手がよさそうです。あとは区切り文字にスペースを追加できればいいだけなのですが…。
No.1
- 回答日時:
ちゃんとマクロを見ていなくて申し訳ないですが・・・
下の方の SetDelimiterで入力している変数「DeLimiter」がセパレータなので、これを複数扱えるように変更すればよいのでは?
あとは 「Delimiter」を検索して、そこで処理している内容を2つのセパレータで行えば良いと思われます。
セパレータがスペースとタブに決め打ちなら、Constなんかで最初に定義しておいて、入力ルーチンを飛ばしてしまってもいいかも。
回答ありがとうございます。
エクセルVBA初心者で、webのサンプルプログラムをあさりながら勉強している最中なのですが、今回のようなサンプルプログラムは自分にとってはまだ難易度がかなり高いです。
そもそも、「Tab」をどのように設定し、どこで指定しているのかわかりません。初心者的にはどこかに" "(←Tabで入力される空白と考えてください。)というような場所が存在していると考えてしまいますが、このプログラムにはどこにも存在していません。DeLimiterに「Tab」として処理される何かを入れているのかとは思いますが、具体的にどのようにしているかまったくわかりません。よろしければもう少し詳しく説明していただけますでしょうか。
自分でもいろいろ調べてみますが…。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 特定の文字を簡単な操作で半角スペースに変換するか削除したい 2 2022/11/01 10:35
- C言語・C++・C# [C言語] コメント文字列を無視して、数値データを読み込むプログラム部分について 5 2022/10/05 11:03
- Word(ワード) 写真3枚をA4に貼り付けたい 5 2023/07/03 14:36
- Visual Basic(VBA) VBAで出力したCSVファイルの先頭にカンマを挿入したい 5 2022/10/14 12:20
- Excel(エクセル) 【VBA】指定フォルダに格納中のテキストファイルをエクセルで処理し結果のエクセルを新規フォルダに保存 1 2022/03/25 14:19
- Visual Basic(VBA) エクセルVBAでメールの自動作成の モジュールを作ったのですが、txtファイルから読み込んだ本文が文 2 2022/07/20 15:01
- Excel(エクセル) エクセルのVBAについて とあるサイトのコードを参考に、CSVの文字化けを直すVBAを作成しているの 7 2022/11/04 14:15
- Ruby ruby 1 2022/06/10 13:31
- Excel(エクセル) PowerQueryに詳しい方教えてください(Office365) 1 2022/07/24 21:11
- その他(Microsoft Office) Excelの条件付き書式についての質問です。 2 2022/09/08 01:25
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ローマ字→カタカナへ変換(エク...
-
Excel VBA のdebug(F8キー) が...
-
EXCELのセルへ、デジタル時計を...
-
Excelを開いた時に表示さ...
-
マクロ 実行ボタンを押さずに...
-
複数ファイルにある特定のシー...
-
【Excel VBA】エラー番号400
-
Excelのワークシート上に検索窓...
-
エラーになってないのにVBA...
-
エクセルで複数のシートをまと...
-
EXCEL2000 VBA マクロ実行中に...
-
TeraTermのマクロについて
-
マクロ ブックをマクロなしでコ...
-
PowerPointでクリックしたオブ...
-
Excelマクロでオプションボタン...
-
エクセルで土日列の非表示方法...
-
ワードで画像を自動で挿入する方法
-
VBAが止まらない
-
エクセル グラフの軸の最小値最...
-
Accessのクエリを実行するショ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ローマ字→カタカナへ変換(エク...
-
複数ファイルにある特定のシー...
-
マクロ 実行ボタンを押さずに...
-
EXCELのセルへ、デジタル時計を...
-
Excelを開いた時に表示さ...
-
エラーになってないのにVBA...
-
Excel VBA のdebug(F8キー) が...
-
ワードからエクセルへ貼り付け...
-
エクセルのマクロ機能で前のシ...
-
Excelのワークシート上に検索窓...
-
モジュール内のマクロを全て実...
-
エクセル グラフの軸の最小値最...
-
EXCEL 複数のシートの同一の位...
-
エクセルで複数のシートをまと...
-
【Excel VBA】エラー番号400
-
Excelマクロでオプションボタン...
-
Wordの画面を左右にスクロール...
-
マクロ ブックをマクロなしでコ...
-
Wordで「原稿用紙○枚」を換算す...
-
AccessのテーブルデータをExcel...
おすすめ情報