Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


4631 / 13646 ツリー ←次へ | 前へ→

【55281】テキストファイル(CSV)に変換 KOCCI 08/4/25(金) 15:53 質問[未読]
【55283】Re:テキストファイル(CSV)に変換 ハチ 08/4/25(金) 16:12 発言[未読]
【55284】Re:テキストファイル(CSV)に変換 neptune 08/4/25(金) 16:18 発言[未読]
【55285】Re:テキストファイル(CSV)に変換 テト 08/4/25(金) 16:33 回答[未読]
【55289】Re:テキストファイル(CSV)に変換 KOCCI 08/4/25(金) 18:38 発言[未読]
【55290】Re:テキストファイル(CSV)に変換 VBWASURETA 08/4/25(金) 19:36 発言[未読]
【55288】Re:テキストファイル(CSV)に変換 Yuki 08/4/25(金) 17:06 発言[未読]
【55295】Re:テキストファイル(CSV)に変換 Hirofumi 08/4/25(金) 23:16 回答[未読]
【55327】Re:テキストファイル(CSV)に変換 KOCCI 08/4/28(月) 9:05 発言[未読]
【55473】Re:テキストファイル(CSV)に変換 kanabun 08/5/6(火) 9:33 回答[未読]
【55486】Re:テキストファイル(CSV)に変換 KOCCI 08/5/7(水) 12:42 質問[未読]
【55488】Re:テキストファイル(CSV)に変換 neptune 08/5/7(水) 13:22 発言[未読]
【55489】Re:テキストファイル(CSV)に変換 kanabun 08/5/7(水) 13:48 回答[未読]
【55491】Re:テキストファイル(CSV)に変換 kanabun 08/5/7(水) 14:52 発言[未読]
【55492】Re:テキストファイル(CSV)に変換 neptune 08/5/7(水) 15:30 発言[未読]
【55493】Re:テキストファイル(CSV)に変換 kanabun 08/5/7(水) 16:36 お礼[未読]
【55496】Re:テキストファイル(CSV)に変換 neptune 08/5/7(水) 22:09 お礼[未読]

【55281】テキストファイル(CSV)に変換
質問  KOCCI  - 08/4/25(金) 15:53 -

引用なし
パスワード
   お世話になっております。
ExcelのシートをCSVファイルに変換しようとしています。
ただ、CSVといいながら、セパレータはカンマではなく@にしたいのです。
Writeステートメントを利用しようとしていますが、@も文字列として書き出されてしまい困っています。
対象列は5つ(A〜E)で、それぞれのセルは文字か空白です。

"abcdef"@""@"xyz"@"lmn123"@""

のように出力させたいのですが、現在は

"abcdef","@","","@","xyz","@","lmn123","@",""

です。Writeステートメントにはこだわりません、正しく出力する方法はありますでしょうか?

【55283】Re:テキストファイル(CSV)に変換
発言  ハチ  - 08/4/25(金) 16:12 -

引用なし
パスワード
   ▼KOCCI さん:
>お世話になっております。
>ExcelのシートをCSVファイルに変換しようとしています。
>ただ、CSVといいながら、セパレータはカンマではなく@にしたいのです。
>Writeステートメントを利用しようとしていますが、@も文字列として書き出されてしまい困っています。

まずは、どのようなコードでその現象になるのか、
コードを提示されるほうが早く解決すると思います。

【55284】Re:テキストファイル(CSV)に変換
発言  neptune  - 08/4/25(金) 16:18 -

引用なし
パスワード
   ▼KOCCI さん:
こんにちは

>"abcdef"@""@"xyz"@"lmn123"@""
↑はCSV形式ではありません。

>"abcdef","@","","@","xyz","@","lmn123","@",""
↑がCSV形式ですよ。正しく出力されていますね。

目的がわからないのでそれ以上は言えませんけど。
CSV形式を必要ならこれで良いんじゃないですか?

【55285】Re:テキストファイル(CSV)に変換
回答  テト  - 08/4/25(金) 16:33 -

引用なし
パスワード
   皆さん言われている通り、CSV形式ではないね。
ASV形式ってことかな?w

で、本題だけど、CSV形式で出力後、テキストファイルで開いて
,"@" → @
に全変換させればいいんじゃないの?
その方が楽な気がするけど…。

【55288】Re:テキストファイル(CSV)に変換
発言  Yuki  - 08/4/25(金) 17:06 -

引用なし
パスワード
   ▼KOCCI さん:
こんにちは。

>ただ、CSVといいながら、セパレータはカンマではなく@にしたいのです。
>対象列は5つ(A〜E)で、それぞれのセルは文字か空白です。
>
>"abcdef"@""@"xyz"@"lmn123"@""
>
>のように出力させたいのです

参考に

Sub Macro2()
  Dim FName  As String
  Dim i    As Long
  Dim j    As Long
  Dim lCol  As Long
  Dim vD()  As Variant
  Dim vA   As Variant
  Dim strA  As String
  
  FName = "D:\Excel\Test7\CSV_AT.CSV"
  
  With Worksheets(1)
    vA = .Range("A1:D" & .Range("A" & .Rows.Count).End(xlUp).Row)
    lCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
    ReDim vD(1 To lCol)
  End With
  
  Open FName For Output As #1
    For i = 1 To UBound(vA)
      For j = 1 To lCol
        vD(j) = Chr(34) & vA(i, j) & Chr(34)
      Next
      strA = Join(vD, "@")
      Print #1, strA
    Next
  Close #1
End Sub

【55289】Re:テキストファイル(CSV)に変換
発言  KOCCI  - 08/4/25(金) 18:38 -

引用なし
パスワード
   申し訳ございません、確かにCSVではありませんでしたね。

社内で海外製のソフトを導入することになり、外部よりExcelで与えられているデータをテキストファイルに変換する必要がありました。
このソフトへデータをインポートするための条件が与えられております。

1.セパレータをカンマではなく@を使用
2.5つの文字列は”で囲むこと
3.改行はCRもしくは<OK>という文字

そして社内利用者からの条件が、1回のクリックもしくは動作でExcelデータからテキストファイルを作ること です。

出来上がったCSVを変換が確かに一番楽そうですけど…、他に方法がない限り却下になります。逆にいえば方法がなければ、これでいけるので、「ない」という確証がほしいのですが。申し訳ございません。

【55290】Re:テキストファイル(CSV)に変換
発言  VBWASURETA  - 08/4/25(金) 19:36 -

引用なし
パスワード
   こんばんは。

ま、テキストに対して文字を書き込むだけだけなので、
速さとかこだわらなければごり押しのやりかたで書けば色々できますよ。

こんな感じのソースとか汚いソースですけど。

Sub OutPut()
  Dim OutTxt As String
  Dim x As Long
  Dim y As Long
  Dim free As Integer
  
  y = 1
  OutTxt = ""
    
  With Sheets(1)
    Do While .Cells(y, 1) <> "" 'セル行
    
      If (OutTxt <> "") Then OutTxt = OutTxt & vbCrLf '改行
      
      For x = 1 To 5 'セル列
        If .Cells(y, x) <> "" And .Cells(y, x + 1) <> "" Then
          OutTxt = OutTxt & """" & .Cells(y, x) & """" & "@"
        Else
          OutTxt = OutTxt & """" & .Cells(y, x) & """"
        End If
      Next x
           
      OutTxt = OutTxt & "<CR>"
      
      y = y + 1
    Loop
  
  End With
  
  free = FreeFile
  
  Open "C:\OutPut.csv" For Output As #free
    Print #free, OutTxt
  Close #free
    
End Sub

【55295】Re:テキストファイル(CSV)に変換
回答  Hirofumi  - 08/4/25(金) 23:16 -

引用なし
パスワード
   こんなのでも

Option Explicit

Public Sub OutPutCsv()

  Dim vntFileName As Variant
  Dim rngTarget As Range
  Dim strPrompt As String
  Dim strTitle As String
  
  strPrompt = "Csv出力するRangeを選択して下さい"
  strTitle = "Csv出力"
  
  On Error GoTo ErrorHandler
  
  '選択範囲の取得
  Set rngTarget = ActiveSheet.UsedRange
  
  'Default出力名の設定
  vntFileName = ThisWorkbook.Path & "\" & "TestFile"
  
  '出力名を取得
  If Not GetWriteFile(vntFileName, ThisWorkbook.Path) Then
    GoTo ErrorHandler
  End If
  
  'ファイルに出力
  CsvWrite vntFileName, rngTarget, vbCr
  
  MsgBox "処理が終了しました", vbInformation
  
ErrorHandler:

  Set rngTarget = Nothing
  
End Sub

Private Sub CsvWrite(ByVal strFileName As String, _
           ByVal rngTarget As Range, _
          Optional strRetCode As String = vbCrLf)

  Dim dfn As Integer
  Dim i As Long
  Dim j As Long
  Dim strBuf As String
  Dim lngCount As Long
  Dim vntField As Variant
    
  '空きファイル番号を取得します
  dfn = FreeFile
  '出力ファイルをOpenします
  Open strFileName For Output As dfn
    
  With rngTarget
    lngCount = .Columns.Count
    For i = 1 To .Rows.Count
      '1行分のDataをシートから読みこむ
      vntField = .Item(i, 1).Resize(, lngCount)
      '出力1レコード作成
      strBuf = ComposeLine(vntField, "@") & strRetCode
      '1レコード書き出し
      Print #dfn, strBuf;
    Next i
  End With
  
  '出力ファイルを閉じる
  Close #dfn
  
End Sub

Private Function ComposeLine(vntField As Variant, _
            Optional strDelim As String = ",") As String
'  レコード作成

  Dim i As Long
  Dim strResult As String
  Dim strField As String
  Dim lngFieldEnd As Long
  Dim vntFieldTmp As Variant
  
  'もし、データが複数なら
  If VarType(vntField) = vbArray + vbVariant Then
    vntFieldTmp = vntField
  Else
    ReDim vntFieldTmp(1 To 1, 1 To 1)
    vntFieldTmp(1, 1) = vntField
  End If
  'データ数の取得
  lngFieldEnd = UBound(vntFieldTmp, 2)
  'データ数繰り返し
  For i = 1 To lngFieldEnd
    'Csv1出力の場合
    strField = PrepareCsv1Field(vntFieldTmp(1, i))
    '結果変数にフィール文字列を加算
    strResult = strResult & strField
    'データカウントがデータ数未満の場合
    If i < lngFieldEnd Then
      '区切り文字を結果変数に加算
      strResult = strResult & strDelim
    End If
  Next i
  
  ComposeLine = strResult
  
End Function

Private Function PrepareCsv1Field(ByVal vntValue As Variant) As String

' Csv1出力形式の調整

  Dim i As Long
  Dim lngPos As Long
  Const strQuot As String = """"
  
  '引数の変数内部形式に就いて
  Select Case VarType(vntValue)
    Case vbString  '文字列型
      'ダブルクォーツの処理
      i = 1
      lngPos = InStr(i, vntValue, strQuot, vbBinaryCompare)
      Do Until lngPos = 0
        vntValue = Left(vntValue, lngPos) & strQuot & Mid(vntValue, lngPos + 1)
        i = lngPos + 2
        lngPos = InStr(i, vntValue, strQuot, vbBinaryCompare)
      Loop
      '両端にダブルクォーツを付加
      vntValue = strQuot & vntValue & strQuot
    Case vbDate   '日付型
      '日付が時分秒を持つなら
      If TimeValue(vntValue) > 0 Then
        vntValue = Format(vntValue, "yyyy/mm/dd h:mm:ss")
      Else
        vntValue = Format(vntValue, "yyyy/mm/dd")
      End If
  End Select
  
  PrepareCsv1Field = CStr(vntValue)

End Function

Private Function GetWriteFile(vntFileName As Variant, _
            Optional strFilePath As String) As Boolean

  Dim strFilter As String
  Dim strInitialFile As String
  
  'フィルタ文字列を作成
  strFilter = "CSV File (*.csv),*.csv," _
        & "Text File (*.txt),*.txt"
  '既定値のファイル名を設定
  strInitialFile = vntFileName
  '読み込むファイルの有るフォルダを指定
  If strFilePath <> "" Then
    'ファイルを開くダイアログ表示ホルダに移動
    ChDrive Left(strFilePath, 1)
    ChDir strFilePath
  End If
  '「ファイルを保存」ダイアログを表示
  vntFileName _
    = Application.GetSaveAsFilename(vntFileName, strFilter, 2)
  If vntFileName = False Then
    Exit Function
  End If

  GetWriteFile = True
  
End Function

【55327】Re:テキストファイル(CSV)に変換
発言  KOCCI  - 08/4/28(月) 9:05 -

引用なし
パスワード
   皆様

遅くなりましたが、たくさんの例文ありがとうございます。
1つ1つ検証して、やってみようと思います、
質問がありましたら出したいので、もうしばらくここは
あけておきたいと思います。

【55473】Re:テキストファイル(CSV)に変換
回答  kanabun  - 08/5/6(火) 9:33 -

引用なし
パスワード
   ▼KOCCI さん:
こんにちは

ワークシートの出力範囲をCOPYすると、データがクリップボードに
転送されます。クリップボード内の区切りはTABコードです。
-----------------------
あ い う え
A  B  C  D

このTABを "@" に置換し、さらに行末の改行コードを "<改行>"に置換すると
↓のような文字列ができあがります。
-----------------------
"あ"@"い"@"う"@"え"
"A"@"B"@"C"@"D"

Sub Try1()
 Const z = """"
 Const zCrLfz = z & vbCrLf & z
 Const CLSID_DataObject = "1C3B4210-F441-11CE-B9EA-00AA006B1A69"
 Dim ss As String
 
 ActiveSheet.UsedRange.Copy
 With GetObject("new:" & CLSID_DataObject)
  .GetFromClipboard
  ss = .Gettext
 End With
 ss = Replace(z & ss, vbTab, """@""")
 ss = Replace(ss, vbCrLf, zCrLfz)
 ss = Left$(ss, Len(ss) - 1)
 
 Dim io As Integer
 Dim myText As String: myText = "D:\(Data)\Try1.txt"
 io = FreeFile()
 Open myText For Output As io
  Print #io, ss;
 Close io
 
End Sub

【55486】Re:テキストファイル(CSV)に変換
質問  KOCCI  - 08/5/7(水) 12:42 -

引用なし
パスワード
   kanabunさま

お休み中(でしょうか?)、ありがとうございました。
クリップボードを利用する手があったのですね。なるほど目からうろこです。
とても勉強になりますが、ごめんなさい、解説をお願いしたく、

> Const CLSID_DataObject = "1C3B4210-F441-11CE-B9EA-00AA006B1A69"

これはどういったものでしょうか?
宜しくお願いいたします。

【55488】Re:テキストファイル(CSV)に変換
発言  neptune  - 08/5/7(水) 13:22 -

引用なし
パスワード
   ▼KOCCI さん:
こんにちは

>kanabunさま
ではないですが、私も判らなかったので調べました。

>> Const CLSID_DataObject = "1C3B4210-F441-11CE-B9EA-00AA006B1A69"
>
>これはどういったものでしょうか?
Microsoft Forms 2.1 DataObject
のClassIDですね。

クリップボードを扱うDataObjectを使用する為でしょう。
ですから、Microsoft Formsを参照設定しておけば不要でできると思いますよ。

【55489】Re:テキストファイル(CSV)に変換
回答  kanabun  - 08/5/7(水) 13:48 -

引用なし
パスワード
   ▼KOCCI さん:
>とても勉強になりますが、ごめんなさい、解説をお願いしたく、
>
>> Const CLSID_DataObject = "1C3B4210-F441-11CE-B9EA-00AA006B1A69"
>
>これはどういったものでしょうか?

こんにちは。
説明なしで、失礼をばいたしました。
実は以下のような事情を説明するのがめんどかったので、
スキップしてました。

上のサンプルでは、
クリップボードの文字列を取得するために
DataObject というオブジェクトを使っていますが、
これは MSForms ユーザーフォームに付属するもので、
VBE のメニュ−から ツール>参照設定 で
 Microsoft Forms 2.0 Object Library
にチェックを入れると利用可能になります。
ところが、お使いのPCの環境によっては ツール>参照設定 の
リストに Microsoft Forms 2.0 Object Library がないことが
あります。
これまで、そのような場合の対処方法として、
VBE の挿入 メニュ−から ユーザーフォームをプロジェクトに
追加する、という方法が用いられてきました。ユーザーフォームを
挿入すると 配下の DataObject への参照が成立する、というわけです。
このばあい、挿入したUserForm そのものは すぐ解放してもかまわない、
UserForm を解放しても DataObjectへの参照は保持されている、
ということです。

さて、WScriptオブジェクトなどの COMオブジェクトを使うとき、
事前に参照設定する方法と、
プログラム実行時に動的に CreateObject する方法があるのは
ご存知ですよね.
 Set Fso = CreateObject("Scripting.FileSystemObject")
とか、
  Set dic = CreateObject("Scripting.Dictionary")
という構文を見かけられたことがあるかと思いますが、
こういう風に、事前に参照設定せずとも DataObject が
実行時に動的に CreateObject できれば、お使いの環境で
参照設定のウィンドウに
Microsoft Forms 2.0 Object Library がなくても
かまわないわけです。
ところが、 上の例に倣って、
 Set Dto = CreateObject("MSForms.DataObject")
とやっても、DataObject は Createできないのです。

そこで、他の掲示板で shira さんが紹介された方法を
用いると、Set Dto = CreateObject("MSForms.DataObject")
と結果同じことができるようになるってわけです。
以下、その時の shira さんの解説を引用します

> 以前に、参照設定せずに MSForms.DataObject
> のインスタンスを作成したいという旨の質問が
> あった時に、APIで作成する方法を回答しましたが、
> Win2000/XP以降のOSでは、上のサンプルで使って
> いるような、newモニカの機能もありましたね。
>
>   Const CLSID_DataObject = "1C3B4210-F441-11CE-B9EA-00AA006B1A69"
>   With GetObject("new:" & CLSID_DataObject)
>     .SetText "Test"
>     .PutInClipboard
>   End With
>
> この方がずいぶんお手軽だと思います。
> Office2000(VBA6)以降では、上記のGetObjectを
> CreateObjectに変えても動くと思います。
> でも個人的には、GetObjectの方が適切と考えます。

【55491】Re:テキストファイル(CSV)に変換
発言  kanabun  - 08/5/7(水) 14:52 -

引用なし
パスワード
   >> CreateObjectに変えても動くと思います。
>> でも個人的には、GetObjectの方が適切と考えます。

CreateObjectメソッドとGetObjectメソッド
については、
h t t p://www.atmarkit.co.jp/fwin2k/operation/wsh03/wsh03_02.html
あたりが参考になりますか?

【55492】Re:テキストファイル(CSV)に変換
発言  neptune  - 08/5/7(水) 15:30 -

引用なし
パスワード
   ▼kanabun さん:
こんにちは

何点か教えてください。

質問1
kanabun さんのおっしゃるには
> Microsoft Forms 2.0 Object Library
と言う事ですが、私の環境では、versionが2.1となっています。
CLSIDは固有のもので生成される毎に違ったものになると記憶しています。
従って、バージョンが変わると変わると思っていましたが、
作成時に指定できるんですか?(ちょっとググッたけど判りませんでしたので。)

質問2
>ところが、お使いのPCの環境によっては ツール>参照設定 の
>リストに Microsoft Forms 2.0 Object Library がないことが
>あります。
どのバージョンにしろOfficeがインストールされている場合、
どのような環境でそのような状況になるのでしょうか?
参考のために教えていただけませんか?

#---------以下、他の掲示板でのkanabun さんの質問に対して---------
user登録までしてあそこを利用したいとは思いませんのでここですみません。

日本語の変数などの話ですが、変数の話ではないですが、経験談を

VB6以前の場合、例えばプロジェクト名は日本語を使えません。
その他、日本語のディレクトリ名を使用していると、不具合が起こる
事がありました。(修正はされたと思います。?)
.netになってからも、日本語の扱いは面倒になったような気がします。

又、開発関係のツール例えば身近な所で、英語で作られたHTML Help workshop
などは、日本語のディレクトリ名にインストールしようとすると失敗します。

それやこれやで、今だに、開発関係のディレクトリには英数字で、出来る限り
8文字形式のディレクトリ名をつけています。

所詮は英語圏の開発ツールなので、あまり信用できないと言うところです。
+IMEの切り替えが面倒なので。
あっ、プリフィクスも付けにくいですよね。

お邪魔しました。

【55493】Re:テキストファイル(CSV)に変換
お礼  kanabun  - 08/5/7(水) 16:36 -

引用なし
パスワード
   neptune さん、こんにちは。

前後しますが、
> 質問2
> >ところが、お使いのPCの環境によっては ツール>参照設定 の
> >リストに Microsoft Forms 2.0 Object Library がないことが
> >あります。
> どのバージョンにしろOfficeがインストールされている場合、
> どのような環境でそのような状況になるのでしょうか?

Microsoft Forms 2.0 Object Libraryが、
参照設定のリストにないことはあるようです。
これについても、他の掲示板で shira さんがあるとき解説されてますので、
またまた無断転載させてください

>   shira 2006/04/08(土) 10:38:08
> こんにちは。   
> MSFormsのライブラリが標準で参照設定リストに   
> 表示されないのは、そういう仕様(そのように   
> レジストリに登録されている)だからですね。   
>   
> 逆に、何もしていない状態で このライブラリが一覧に   
> 存在する環境というのは、同じExcel内で開かれている   
> 他のブック(アドインも含みます)が参照しているのが   
> 原因だったりしませんかね?   
>
> > 2.一度、参照設定するとそのブックは参照設定がはずせなく   
> > なる。   
>
> 手作業では、ですね。   
> ReferencesのRemoveメソッドを使うと外せますね。   
>
> ちなみに、このライブラリを常に一覧に表示させたければ、   
> (前述のようにアドイン等で参照設定するのも有効な方法だと思いますが)   
>
> レジストリの   
> HKEY_CLASSES_ROOT\   
> TypeLib\{0D452EE1-E08F-101A-852E-02608C4D0BB4}\2.0\FLAGS   
> の標準の値(文字列)が標準で 2 になっているのを、   
> 0 に変更しておけばよいと思います。   
> (実行される場合は自己責任でお願いします)

質問1の
MSFormsの バージョンの件ですが、ぼくにもよく分かりません。

ちなみに、今使ってるPCのレジストリを覗いてみたところ、(Vista)
1C3B4210-F441-11CE-B9EA-00AA006B1A69
というCLSID 
パスは HKEY_CLASSES_ROOT\CLSID\{1C3B4210-F441-11CE-B9EA-00AA006B1A69}
データは  Microsoft Forms 2.1 Object Library
と、たしかになってました。
値が Microsoft Forms 2.1 で始まるものは他には
  ControlPalette
  ControlSelector
  SubForm95
  Font
  ...
などありましたが、DataObject 以外は どこで使ってるのか
よく分かりませんです。

一方Version 2.0の CLSID {0D452EE1-E08F-101A-852E-02608C4D0BB4}
Microsoft Forms 2.0 もまたあるようで、
値が Microsoft Forms 2.0 で始まるものは
 Form, CommandButton,ListBox, ComboBox, CheckBox など
通常のコントロールはみな version 2.0 でした。


> #---------以下、他の掲示板でのkanabun さんの質問に対して---------
> user登録までしてあそこを利用したいとは思いませんのでここですみません。
>
> 日本語の変数などの話ですが、変数の話ではないですが、経験談を

ありがとうございます。参考にさせていただきます。m(__)m

【55496】Re:テキストファイル(CSV)に変換
お礼  neptune  - 08/5/7(水) 22:09 -

引用なし
パスワード
   ▼kanabun さん:
こんにちは

ご返答ありがとうございます。

質問1ですが、やはり、固有のIDが付けられるようですね。ちょっと
安心しました。
VBEの参照設定の画面で同じ名前でバージョンだけ違うのがありますよね。
それらは当然ClassIDが違います。だからバージョン違いのものが2つ
表示され、2つとも使用できます。
私のformsのバージョンも、こんな感じになるんでしょうね。

質問2の方ですが、仕様というからにはインストールの際なにか設定が
あったんですかね。
いつもフルでインストールするものですから覚えていません。

なにはともあれ少し疑問が解けたような気がします。
ありがとうございました。

4631 / 13646 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free