• ベストアンサー

エクセルVBAでのファイル入力(GET)

1レコードのとあるテキストファイルがあります。 形式は、‘\’+「文字コード(HEX)」 の羅列です。 \20\20\20\20\20\31\32\33\34\35\36\37\38・・・ 目的としては、このファイルから\を取り除いて、データ項目別に 読み込み、文字に変換することです。 即ち、上記の例だと   △△△△△12345678・・・   ←項目1→←項目2→ といった感じになります。(△:スペース) そこで、\を外した文字列をセットする際に、最初のコードでは うまくいかず、その後試してみながら結果的にはうまくいきました。 ですが、最初のコードでうまくいかなかった理由というのが理解 できません。 どこがおかしかったのでしょうか? ≪正常に行かなかったコード≫----------------- 'ファイルオープン Open(パス)For Binary Access Read As #FileNum '1つ分の項目のデータをGET For j = 1 To n   Get #intFileNum, j , tempStr   If tempStr <> "\" Then     Str = Str & tempStr Else   End If Next j ※これだと「tempStr」には何もセットされず、結果と  して「Str」も空になってしまいます。 ≪正常に行ったコード≫---------------------- 'ファイルオープン&全てGET Open(パス)For Binary Access Read As #FileNum Get #FileNum, , Buff '1つ分の項目のデータを入力 For j = 1 To n   tempStr = Mid(Buff, j , 1)   If tempStr <> "\" Then     retStr = retStr & tempStr   Else   End If Next j ※これだと正常に「tempStr」に文字がセットされます。

質問者が選んだベストアンサー

  • ベストアンサー
  • R_Moon
  • ベストアンサー率60% (9/15)
回答No.3

#1です。 あてずっぽで回答しているのは失礼なので これでだめならやめますが、 tempStrを定義した時に、  Dim tempStr as String * 1 とか  tempStr = String(1," ") の様にbyte数を明示的に示してみたらどうでしょうか?

orange777
質問者

補足

ありがとうございます。 どちらの方法でも、うまく行きました。 1Byteの大きさの変数しかダメなんでしょうね。(おそらく)

その他の回答 (3)

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.4

GetやBinaryを使わなくても出きる例。 Sub test01() Open "c:\my documents\test03.txt" For Input As #1 Open "c:\my documents\test04.txt" For Output As #2 Line Input #1, a ' MsgBox a s = Split(a, "\") st = "" For i = 1 To UBound(s) n = Val(s(i)) st = st & Chr(16 * Int(n / 10) + (n Mod 10)) Next i MsgBox st Print #2,st Close #1 Close #2 End Sub メモ帳に\20\20\20\20\20\31\32\33\34\35\36\37\38を貼りつけ、test03.txtの名前で保存。 上記を実行。 「     12345678」になりました。 質問の正面からの答えでなくて済みません。質問者の方法は難しい方法になっている気がして。 質問のコードには Chr(16 * Int(n / 10) + (n Mod 10))に当たる部分が無いようですが、宜しいのでしょうか。

orange777
質問者

補足

ありがとうございます! 確かに、コードがすっきりしますね。 >質問のコードには Chr(16 * Int(n / 10) + (n Mod 10))に当たる部分が無いようですが、宜しいのでしょうか。 ここも自分でコードを組んでいるのですが、STEP数が3倍くらいあります。 なにせ、VAL関数の存在を今知りましたので・・・。 ちなみに、INPUTとGETは、どういう観点で使い分ければ良いのでしょうか?

  • R_Moon
  • ベストアンサー率60% (9/15)
回答No.2

#1で回答した者です。 すみません。今試す環境がないので予測で言ってるのですが、 「tempStrには何も入っていかない」というのは     Str = Str & tempStr の部分での、tempStrでしょうか?   Get #intFileNum, j , tempStr   debug.print j,tempStr ←   If tempStr <> "\" Then これでtempStrへの格納がわかると思いますが ここで何も入っていないとしたら、ごめんなさい。ちょっとわからないですね。

orange777
質問者

補足

度々、ありがとうございます。 そうなんです。 tempStrに何も格納されないのです。(String型の変数なのですが) なぜでしょう・・・?

  • R_Moon
  • ベストアンサー率60% (9/15)
回答No.1

ループの中で、 debug.print j,tempStr の一行を加えて、イミディエイトウインドで 見比べてみたらどうでしょうか? うまくいかなかった理由はすぐわかると思います。

orange777
質問者

補足

ありがとうございます。 最初、ステップインでひとつひとつ確認しても、やはりtempStrには何も入っていかなかったんです。 どこか根本的な構文が間違っているのかと思いまして・・・。

関連するQ&A

  • VC++でのメールの添付ファイル受信

    http://www.masukawa.co.jp/sdk/40.html のサイトを参考にしてソースを組んでいます。 ですが BOOL Pop3RecvDataToFile(SOCKET sock, int i, char *filename) { char *get, tmp, buff[BUFF_SIZE]; int size, pos; FILE *fp; if (!SockCmd1(sock, "RETR %d", i, buff, "+OK")) return FALSE; if ((fp = fopen(filename, "wb")) == NULL) return FALSE; tmp = '\0'; pos = 0; for (;;) { size = recv(sock, buff, BUFF_SIZE, 0); for (get=buff; get<(buff+size); get++) { if (*get=='\0' || *get=='\r') continue; if (++pos == 1) { if (*get != '\n') { tmp = *get; continue; } } else if (pos == 2) { if (tmp=='.' && *get=='\n') goto FINISH; if (tmp!='.' || *get!='.') fputc(tmp, fp); } fputc(*get, fp); if (*get == '\n') pos = 0; } } FINISH: fclose(fp); return TRUE; } のfor分で無限ループしています。 その理由がわかりません。どうすればよいでしょうか?

  • ExcelVBAでの2バイト文字の入力方法

    ExcelVBAを用いてファイルを入力し、そこから項目毎にデータを分割して各セルへ値を設定するという処理を作っています。 [ファイルイメージ(1レコードのみ)]  12345678900000000△△△△△・・・  ←項目1→←項目2→←項目3→・・・ 今までは、ファイルをバイナリアクセスモードでOpenし、その後に For i = 1 to n Get #FileNum, i, b next i というように、バイト位置(Count)をずらしながら、1バイト単位に変数bに入れて、 処理を行ってました。 これまではファイル内のデータが全て1バイト文字だったのですが、全角2バイト 文字が含まれる ようになり、どのように処理を行えばファイルを読み込んで全角文字に変換できる のかが分かりません。 初心者的なご質問かもしれませんが、よろしくお願いします。

  • VBで複数のテキストを結合するときの問題

    教えてください!お願いします。 VB6を使って、複数のテキストファイル(~.txtで保存しているもの)を 一つずつ読み込んで、それらを結合して1つのファイルにして リッチテキストボックスに表示する、というツールを作成しています。 一応うまく出来たのですが、ただ、結合した時にそれぞれのテキストの 間にどうしても1行ブランクが入ってしまうんです。 このブランク行を削除して、結合したファイルの継ぎ目がきれいに 続いて表示されるようにする方法はありますでしょうか? ブランク行を全て削除してしまうのではなく、ファイルとファイルの 間に挿入されてしまうブランク行だけをなくしたいのです。 ちなみに Open App.Path & "\" & List1.List(List1.ListIndex) For Input As #FileNum Do Until EOF(FileNum) Line Input #FileNum, ddd gggg = gggg & ddd & vbCrLf Loop Close #FileNum このようにリストに載っているテキストファイルを全部読み込んで、 If Dir(書き出すテキストファイル) = "" Then Open 書き出すテキストファイル For Output As #FileNum Print #FileNum, gggg Close #FileNum Else Open 書き出すテキストファイル For Append As #FileNum Print #FileNum, gggg Close #FileNum End If 書き出すファイルが存在しなければそのまま保存し、書き出すファイルが あれば、そのファイルに追記するというコードにしています。

  • ファイルの読み込みについて

    いつもお世話になっています。 早速質問なのですが、VBのファイル処理において固定長データのテキストファイル読み込みの処理で、 固定長データの改行コードがChr(10)になっているデータがあります。 下記のどのOpenステートメントを使用しても、1行読み込みではなく全行読み込まれてしまうのです。 ↓ファイルモード (1)Open strInFile For Input As #intInFile (2)Open strInFile For Random As #intInFile Len=文字数 (3)Open strInFile For Binary As #intInFile ちなみに読み込みのモードは ・Line Input ステートメント ・Get ステートメント の2つを使用してみました。 改行コードの種類に依存せずにデータを1行読み込む方法を教えていただきたいです。

  • Excel VBAにて別のExcelファイルを開く

    現在、ExcelファイルVBAにて別のExcelファイルを開こうとしています。FileSystemオブジェクトを利用してオープンはできるのですが、当然そのファイルをどなたかが利用していると「書き込みできません」とのメッセージが出てきます。これを回避するためにオープンするExcelファイルがすでに誰かに開かれているかを判定できる方法はございませんか?WSHやAPIを利用してもかまいません。以下にロジックを書いておきますので、どうかよろしくお願いいたします。緊急度は大変高いです。 'ErrorFileフォルダ内のエクセルファイルが存在するかを判定 Do Until fs.FileExists(buff) = False 'ErrorFile内のエクセルファイルを取得 Set f = fs.GetFile(buff) 'FileSystemオブジェクトでErrorFile\logフォルダ内の同一名称ファイルが存在するかを判定 If fs.FileExists(f.ParentFolder & "\log\" & f.Name) = True Then '存在していたら、ファイルを削除 ←この部分で誰かがファイルを開いているとエラー        fs.DeleteFile f.ParentFolder & "\log\" & f.Name End If 'ErrorFileフォルダ内のファイルをErrorFile\logフォルダに移動 fs.MoveFile f.Path, f.ParentFolder & "\log\" & f.Name 'マクロが動作しているパスにErrorFileフォルダ内のエクセルファイル名をフルパスで取得 buff = ActiveWorkbook.Path & "\ErrorFile\" & Dir("ErrorFile/*.xls", vbSystem) Loop どうか、解決策を返信いただければ幸いです。

  • EXCELのVBAでのCSVファイル読込みと検索

    エクセルのマクロでCSVファイルを読み込み、その行の得意先サブコードをキー項目として別のCSVファイルを検索し電話番号とFAX番号を取得するという作業を下記のようなコードで作成しました。 Dim Obj As Object Dim Path As String Dim FName As String Dim i As Long Dim buf As String Dim tmp As Variant Dim WSH As Variant Dim CN As ADODB.Connection Dim RS As ADODB.Recordset '自分のPCのデスクトップをPathとして設定します。 Set WSH = CreateObject("Wscript.Shell") Path = WSH.SpecialFolders("Desktop") & "\" '得意先マスタ.csvをOPENする際の準備処理 '3行目のPropertiesがCSVファイルの定義(excelをOPENする時とは異なります) Set CN = New ADODB.Connection CN.Provider = "Microsoft.Jet.OLEDB.4.0" CN.Properties("Extended Properties") = "Text;HDR=YES;FMT=Delimited" CN.Open Path '得意先サブマスタ.CSVを開きます。 Open Path & "得意先サブマスタ.csv" For Input As #1 i = 1 Do Until EOF(1) Line Input #1, buf tmp = Split(buf, ",") If i = 1 Then Else Cells(j, 1).Value = Left(tmp(3), 4) '会社コード Cells(j, 2).Value = Right(tmp(3), 4) '店舗コード Cells(j, 3).Value = tmp(3) '会社@店舗 Cells(j, 4).Value = tmp(4) '得意先コード Cells(j, 5).Value = tmp(5) '店舗名 Set RS = New ADODB.Recordset RS.Open "SELECT * FROM 得意先マスタ.csv WHERE 得意先コード = " & tmp(4) & " ", CN If RS.EOF Then Cells(j, 6).Value = "???" Cells(j, 7).Value = "???" Else Cells(j, 6) = RS.Fields("電話番号") Cells(j, 7) = RS.Fields("FAX番号") End If End If i = i + 1 Loop このコードで動作確認すると途中で動作が止まってしまい応答なし状態になってしまいます。どこで止まるかは一定ではありません。CSVファイルの内容も確認したのですが、特におかしいような箇所はありませんでした。 OSはWINDOWS7、EXCELは2016です。 コード自体に修正した方がいいような箇所があればアドバイスいただきたいと思っております。宜しくお願い致します。

  • ファイル入力方法について

    下記の入力ファイルinput.datの内容を出力するプログラムを作っています。 ・1001,1002,・・・はデータ番号 ・データ番号の下は、行数1~20,列数4のデータ ・「DATAEND」で入力停止 1001 aa bb 01 02 cc dd 03 04 1002 ee ff 05 06 gg hh 07 08 ii jj 09 10 1003 kk ll 11 12 mm nn 13 14 DATAEND データ番号なしの入力データを出力するソースが下記のものです。データ番号が入った入力データではうまくファイル入力できません。 大変お手数ですが、教えてください。よろしくお願いします。 #include <stdio.h> #include <stdlib.h> int main(){ int i,j,n=0,N=0,num[20],c[10][20],d[10][20]; char str[20][100],a[10][20][5],b[10][20][5]; FILE *fpi; if((fpi=fopen("input.dat","r"))==NULL){ fprintf(stderr,"Cannot open file input.dat\n"); exit(1); } for(i=0;i<10;i++){ for(j=0;j<20;j++){ fgets(str[i],sizeof(str[i]),fpi); if(sscanf(str[i],"%s %s %d %d",a[i][j],b[i][j],&c[i][j],&d[i][j]) != 4){ break; } n++; } num[i]=n; n=0; if(num[i]==0){ break; } N++; } for(i=0;i<N;i++){ for(j=0;j<num[i];j++){ printf("%s %s %d %d\n",a[i][j],b[i][j],c[i][j],d[i][j]); } printf("\n"); } fclose(fpi); return 0; }

  • ファイルの英字を全部小文字に変換して新規テキストに出力

    テキストファイルの英字を全部小文字に変換して新規テキストに出力するプログラムをつくりましたがうまくいきません。なにがいけないですか? #include <stdio.h> #include <stdlib.h> #include <ctype.h> #define STR_MAX 256 int main(void) { FILE *fi, *fo; /* ファイルポインタ用 */ char fin[100], fout[100]; /* ファイル名用 */ char buff[STR_MAX], *q; /* 文字列用 */ printf("入力ファイル名 : "); /* プロンプト表示 */ gets(fin); /* ファイル名入力 */ printf("出力ファイル名 : "); /* プロンプト表示 */ gets(fout); /* ファイル名入力 */ q = buff;   /* 入力ファイルオープン */ if((fi = fopen(fin, "r")) == NULL){ printf("入力ファイルがオープンできません\n"); exit(1); /* 強制終了 */ }   /* 出力ファイルオープン */ if((fo = fopen(fout, "w")) == NULL){ printf("出力ファイルがオープンできません\n"); exit(1); /* 強制終了 */ } while(fgets(buff, STR_MAX, fi) != NULL){ /* 1行読み込み */ *q = tolower(*q); ++q; fprintf(fo, "%s", buff); /* 1行出力 */ } fclose(fi); /* 入力ファイルクローズ */ fclose(fo); /* 出力ファイルクローズ */ return(0); }

  • マクロで1ファイルに複数の文字コードで出力する方法

    研究室で使用しているツールの文言表示用の テキストファイルを出力するようにマクロを組んだエクセルファイルが有るのですが、 2年続けて中国人の方が研究室に入ってきたため ツールを中国語化しようとツールとエクセルファイルをメンテしているのですが ツールの構造と動作環境の関係から出来たら 日本語→shift-jis 中国語(繁)→big5 中国語(簡)→GB2312 の各文字コードで1つのファイルにまとめて出力したく試行錯誤していたのですが うまい方法が見つからず困っています。 何かヒントになりそうな事柄でもいいので情報お持ちの方が居ましたらお願いします。 ---------------------------------------- ◆シート側 ┏―┳―――┳―――┳―――┓ |ID|日本語|繁体字|簡体字| ┣―╋―――╋―――╋―――┫ |01| 開始 | 開始 | 开始 | ┣―╋―――╋―――╋―――┫ |02| 終了 | 結束 | 结束 | ┣―╋―――╋―――╋―――┫ |03| 編集 | 編輯 | 编辑 | ┗―┻―――┻―――┻―――┛ ・ ・ ・ ◆出力したいテキストファイル 01J  開始 01C1 開始 01C2 开始 02J 終了 02C1 結束 02C2 结束 03J 編集 03C1 編輯 03C2 编辑 ・ ・ ・ ◆コード概要 ※概要説明用に簡略してるので多少変なところがあるかも知れません ファイル出力部分です Dim FileNum As Long Dim text As Object ’オブジェクトを宣言 Set text = CreateObject("ADODB.Stream") ’ADODB.Streamを使用 text.Type = adTypeText text.Charset = "shift-jis" ’文字コード設定 For FileNum = 0 To (SheetCount) ’全シートを対象にシートごとにファイルを出力 text.Open Count = 0 Do While Count < lItemNum(FileNum) ’各シートにおける項目数分 text.WriteText Output(FileNum, Count) ’Outputにシートから読込み出力用に形を整えた全ての文言が入ってます Count = Count + 1 Loop text.SaveToFile ("C:\TEST.txt"), adSaveCreateOverWrite text.Close Next FileNum Set text = Nothing ここでファイルに追記する形にすれば出来るのでは!? とかも 考えたのですがこの出力方法における追記方法が 出力済のデータを再度読み込み、その末尾に新たなデータを追加し 全て出力し直すといった方法しか見つけられなかったため、 結局1種類の文字コードでしか出力できませんでした。 1つのファイルに複数の文字コードでの出力は無理なんでしょうか?

  • VBAでバイナリデータが上手く読めない。

    VBAでバイナリデータが上手く読めない。 もともとC言語でバイナリデータを加工していた事をVBAでやる事になったのですが、上手く読めない。 <VBA> Open inputFileName For Binary As #mFileNo のようにオープンして、 <VBA> Dim a(800) As Byte Get #1, , a のように記述すればC言語のように取得出来ると思ったのですが、上手く取得出来ません。 なんとなく分かった事ですが、800バイトの中に改行文字があった場合、そこまでを変数aに入れるようにすると出来そうなので、Getで改行コードがあった場合はそこまでを読み込むみたいな手段はありますでしょうか。inputだとデータがまったく見れませんでしたのでGetにて対応したいと思っています。 宜しくお願い致します。

専門家に質問してみよう