• 締切済み

UTF-8のデータを複数開いて編集したい

皆様のお力をお貸しください 基本がわかってないために所々おかしなところがあるかも知れませんが宜しくお願いします。 UTF-8で書かれたxmlデータをエクセルで開いて編集して保存したいのですがうまくいきません。 Sub test1() Dim xmlFileName As Variant Dim F_Filter As String Dim i As Integer F_Filter = "データ,*.txt" xmlFileName = Application.GetOpenFilename(filefilter:=F_Filter, MultiSelect:=True, Title:="ファイル選択") If IsArray(xmlFileName) Then For i = 1 To UBound(xmlFileName) Workbooks.OpenText Filename:=xmlFileName(i), _ Origin:=932, StartRow:=1, DataType:=xlDelimited, TextQualifier _ :=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, Semicolon:= _ False, Comma:=False, Space:=False, Other:=False, FieldInfo:=Array(1, 1), _ TrailingMinusNumbers:=True MsgBox xmlFileName(i) ActiveWorkbook.Close Next End If End Sub Origin:=932は Origin:=-535 だと思ってください。(家だとなぜかエラーのため) 一つはこんな感じです。 これだと連続編集できるのですが拡張子がxmlだとスクリプトエラー となってしまうため まず拡張子を手で.txtに変えています。 二つ目は Sub OpenFile() Dim xmlFileName As Variant Dim F_Filter As String Dim NewName As String F_Filter = "データ,*.xml" xmlFileName = Application.GetOpenFilename(filefilter:=F_Filter, MultiSelect:=False, Title:="ファイル選択") If xmlFileName = False Then MsgBox "キャンセルしました" Else NewName = Left(xmlFileName, InStrRev(xmlFileName, ".", -1, vbTextCompare)) & "txt" Name xmlFileName As NewName Workbooks.OpenText Filename:=NewName, _ Origin:=932, StartRow:=1, DataType:=xlDelimited, TextQualifier _ :=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, Semicolon:= _ False, Comma:=False, Space:=False, Other:=False, FieldInfo:=Array(1, 1), _ TrailingMinusNumbers:=True MsgBox xmlFileName ActiveWorkbook.Close Name NewName As xmlFileName End If End Sub これだと拡張子を変更してくれるのですが連続編集できません。 拡張子を自動で変更しつつ連続編集できないものでしょうか。 というのも自作なのですがすべてつぎはぎでできているためうまくできないのです。どうぞ宜しくお願いします。 あわせて編集したあとUTF-8で保存したいのですがこちらのコード もわかりましたら宜しくお願いします。

みんなの回答

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.6

補足:空のシートを一つ使います。また、今回の場合は、保存の際には、ファイル名o.xml という名称になります。上書きはしないようにしました。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.5

こんにちは。 >結果的に取り込むとメモリ不足と表示されて取り込めませんでした。 >2万行程度で数メガほどのデータだからでしょう。減らせは動いてくれます。 >しかし名前の名など一部が文字化けしてしまいます。 最初の方が示したように、直接、ソースを扱うとなると、Office は向かないような気がします。StreamEditor(SE)や、Grep など、TextStream 系のツールほうが便利なような気がしますね。あえて、Excelを使うなら、Excel 2007 や Excel 2003 Professional で加工したほうが早いとは思いますが、今、手元にないので、こういうVBAのコードを作ってみました。 '標準モジュール '------------------------------------------- Sub TestUTF8xml()   Dim F_Filter As String   Dim xmlFileName As Variant   Dim fn As Variant   Dim sText As String   Dim oADO As Object 'ADODB.Stream   Dim i As Long   Dim fn1 As String '出力ファイル名   F_Filter = "xmlファイル,*.xml"   xmlFileName = Application.GetOpenFilename( _   filefilter:=F_Filter, MultiSelect:=True, Title:="ファイル選択")   If IsArray(xmlFileName) = False Then     MsgBox "キャンセルしました"     Exit Sub   End If   Set oADO = CreateObject("ADODB.Stream")      For Each fn In xmlFileName     Cells.Clear     fn1 = Mid(fn, 1, InStrRev(fn, ".") - 1) & "o.xml" '出力ファイル     i = 1     With oADO       .Open       .Charset = "UTF-8"       .Type = 2 'adTypeText       .LoadFromFile fn       .Position = 0       Do While Not .EOS         Cells(i, 1).Value = .ReadText(adReadLine)         i = i + 1       Loop       .Close       '**************       'ここで加工するコードを入れる       '**************       .Charset = "UTF-8"       .Type = 2 'adTypeText       .Open       For i = 1 To Range("A65536").End(xlUp).Row         .WriteText Cells(i, 1).Value, adWriteLine       Next       .SaveToFile fn1, adSaveCreateOverWrite       .Close     End With      Next fn   Set oADO = Nothing End Sub

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.4

こんにちは。 >勉強自体も3行マクロを始めたばかりですのでここまで言われると落ち込んでしまいます。 別に、ご質問者さんに対して直接言っているわけではありません。分からないからお聞きになっているのでしょうから、そういうことに、あまりナーバスに取らないでください。ただ、質問のコードは、ご自身の作られたものですか?もし、どこかで見つけたコードでしたら、それをおっしゃっていただいたほうがよいです。 こうしたらどうか、というアドバイスをしたのですが、それを受け付けないということになると、回答者側では困ってしまいます。 もし、VBAを勉強するなら、初歩から一歩一歩、段階的に学習することをお勧めします。一足飛びには、自分の思ったようには使えないのです。VBAは、一つの流れの中で覚えないと、なかなか、できるようになりません。 元のコードの直接の要望はに対しては、 xmlFileName = Application.GetOpenFilename(filefilter:=F_Filter, MultiSelect:=False, Title:="ファイル選択") ここを、MultiSelect:=True に換えて、xmlFileName が、配列になりますから、その配列変数を、ループで取り出せば可能です。 私がOpenステートメントで考えた方法は、以下のようにすることです。このレベルは初級の範囲ですが、もし、文字化けするなら、方法を変えなくてはならないのですが、この方法が気に入らなかったら、別の方のコメントをお待ちになったほうが良いかと思います。 xml は、Officeでは、高度な処理方法がありますが、Office 2003 では、Professional バージョンが必要になってしまいますし、Office 独特のフォーマットになってしまいます。 テキスト処理するなら、あまり、Office としての利点が得られません。エディタや専用ツールのほうがよいかもしれません。 以下は、マルチセレクトになっていますから、複数ファイルを選ぶことが可能です。また、途中でマクロを解除するとファイルを削除していますから、ファイルがなくなっています。最後までマクロを実行してください。ファイルを削除する代わりに、別名で保存してもよいです。  'Kill fn  nFname = Left$(fn, InStrRev(fn, ".") - 1) & "o.xml" '加える  'nFname = fn '必要に応じて、ファイル名を変更する '-------------------------------------- '標準モジュールのみ '空のシートをひとつ用います。 Sub Test1()   Dim FName() As Variant   Dim nFname As String   Dim fn As Variant   Dim FNum As Integer   Dim TextLine As String   Dim i As Long   Dim c As Variant      i = 1   '新規のシートを作る   With ThisWorkbook    .Worksheets.Add After:=.Worksheets(.Worksheets.Count)   End With   FName = Application.GetOpenFilename("xml ファイル(*.xml),*.xml", , , , True)      If FName(1) = "False" Then Exit Sub   For Each fn In FName          FNum = FreeFile()     Open fn For Input As #FNum     Do While Not EOF(FNum)       Line Input #FNum, TextLine       Cells(i, 1).Value = TextLine       i = i + 1     Loop     Close #FNum     Kill fn 'ファイル削除     'ここに処理を書く               MsgBox fn & "User処理中...."          nFname = fn '必要に応じて、ファイル名を変更する          FNum = FreeFile()     Open nFname For Output As #FNum     For Each c In Range("A1", Range("A65536").End(xlUp))       Print #FNum, c.Text     Next c     Close #FNum     Cells.Clear     i = 1   Next End Sub

tools_2009
質問者

お礼

ありがとうございます コードは最初に書いてある通りつぎはぎです。 調べて書いてはF8で一行ずつ実行しては書き直すなどして書きました。 >こうしたらどうか、というアドバイスをしたのですが、それを受け付けないということになると、回答者側では困ってしまいます。 自分にとってはまだ記録の延長線上です。そのためにがっかりすることを書いたかもしれません。受け入れなかったのではなく意味がわからなかったのです。ごめんなさい そしてコードを示してくれましてありがとうございます。 結果的に取り込むとメモリ不足と表示されて取り込めませんでした。 2万行程度で数メガほどのデータだからでしょう。減らせは動いてくれます。 しかし名前の名など一部が文字化けしてしまいます。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

#2の回答者です。 もうしわけないけれども、今回の全体のコードの流れがしっくりしていないのです。 MsgBox の時で処理するのは分かりましたが、xmlを、勉強されているのでしょうか。あまり、VBAの勉強をされているようには思えないです。 もし、VBA自体を学ぶなら、もう少し、VBAの処理範囲というものを学ばれたほうがよいです。質問のOpenTextで処理すること自体は、記録マクロの延長ですが、それは、VBAでは、便宜的なもので、特別なものだと思います。通常、そのようなことはしません。 コードの内容は、OpenTextのテキスト・オープンで、拡張子をtxt にし、テキスト・コードをワークシート上で広げて行って、それを処理し、テキストで保存(書かれていないが)して、拡張子を変えるというものだと思います。スキルの低い人でないと、この質問そのものを答える人はいないように思います。わざわざ、ワークシートに表示する必要がないと思うのです。 そういうのは、テキストストリームの中で、処理すればよいのですから、以下のようにすればよいです。 Open filename For Input As #1 のように、オープンステートメントでインポートとして、 Open filename For Output As #1 で出力すればよいのです。 ここで、一行のテキストラインが得られますから、修正・置換程度なら、Repalce 関数を使えばよいです。一行書き加えるとなれば、面倒ですが、それも可能です。

tools_2009
質問者

お礼

>コードの内容は、OpenTextのテキスト・オープンで、拡張子をtxt にし、テキスト・コードをワークシート上で広げて行って、それを処理し、テキストで保存(書かれていないが)して、拡張子を変えるというものだと思います。スキルの低い人でないと、この質問そのものを答える人はいないように思います。わざわざ、ワークシートに表示する必要がないと思うのです。 そもそもこのコードはUTF-8で書かれたxmlをエクセルで開き編集処理をしたあとxmlに戻してUTF-8で保存したかったので書いたコードです。 そのままではエラーとなり開けず、テキストでは文字化けするためにこの形となっています。 そして保存が書かれていないのはそのまま保存してしまうとShift JISで保存してしまうためです。そもそもUTF-8にして保存する方法がわかりませんでした。 処理自体もこのマクロを含むブックに書かれたことをxmlデータに追加、変更、削除などをすることです。 book1 A    B        C          D 追加 山田太郎 090-xxxx-xxxx 住所xxxxxxxx ~ 削除 山田花子 090-xxxx-xxxx 住所XXXXXXXX このようなシートがありこれによりxmlデータを編集していく処理です。 レベルが低いと感じておられるようですが私にとってはまだそれは当然だと思っています。 勉強自体も3行マクロを始めたばかりですのでここまで言われると落ち込んでしまいます。 今は自分のしたい事をできる様になるその過程です 初心者であることを逃げ口上には使いたくはないですが始めたばかりですのでコードは歪に見えるかもしれません。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.2

こんばんは。 >自分のスキルアップのためにもエクセルである必要があると考えています。 コードからすると、xml の生のコードがそのままになっているような気がします。xml ファイルを開いて、拡張子を変更して ActiveWorkbook.Close しています。 それでいいなら、 Name テキストファイル名 As xmlファイル名 だけでよいのではありませんか? もちろん、Excelでは、エディタではできない 高度なxml(Excel2003の場合は、Professional版) の編集が可能ですが、それは、別段、マクロで行う必要はありません。

tools_2009
質問者

お礼

ありがとうございます。 >コードからすると、xml の生のコードがそのままになっているような気がします。xml ファイルを開いて、拡張子を変更して ActiveWorkbook.Close しています 処理はここでは割愛して MsgBox xmlFileName としています。 しかし 'ここで処理内容を記載 としておけばよかったですね。 ここのコードでは.xmlをまず.txtに変更した後ブック名を表示して 閉じて.xmlに戻しています ブック名の表示を簡易的に処理と見立てています。

  • t_nojiri
  • ベストアンサー率28% (595/2071)
回答No.1

エクセルじゃないと駄目なんですかね? UTF-8エンコード出来るテキストエディッタ探して編集した方が簡単そうな気がしますが。 http://www3.coara.or.jp/~tarariko/utf8.html

tools_2009
質問者

お礼

返信ありがとうございます。 誰から教えてもらっているというわけではありませんが今年から勉強を始めました。 自分のスキルアップのためにもエクセルである必要があると考えています。

関連するQ&A

  • AND、OR文にすると選択後の編集が出来ない

    Private Sub 選択_Click() If NewRecord Then MsgBox "編集できません。選択しなおしてください。" Me.Undo End If End Sub 上記の命令が効いていないようです。メッセージも出ません。 Private Sub 編集_Click() Dim strFil As String strFil = "[選択]=" & True DoCmd.OpenForm "編集F", , , strFil 'DoCmd.Close acForm, "スタート画面F" '選択.Value = Null End Sub 上記のスタート画面は消したくないので’を付けてあります。 選択.Value=Null でコンパイルエラーが発生していますので’を付けています。 Private Sub 検証_Click() Dim strFil As String If IsNull(Me.ステータスリスト) And IsNull(Me.申請リスト) Then MsgBox ("コンボボックスの選択がされていません") Exit Sub End If If Not IsNull(Me.ステータスリスト) And IsNull(Me.申請リスト) Then strFil = "[ステータス] ='" & Me![ステータスリスト] & "'" End If If IsNull(Me.ステータスリスト) And Not IsNull(Me.申請リスト) Then strFil = "[申請内容] = '" & Me.申請リスト & "'" End If If Not IsNull(Me.ステータスリスト) And Not IsNull(Me.申請リスト) Then If MsgBox("二つの条件でAND検索をしますか", vbYesNo) = vbYes Then MsgBox ("二つの条件でAND検索をします") strFil = "[ステータス] = '" & Me.ステータスリスト & "'and " & "[申請内容]='" & Me.申請リスト & "'" Else MsgBox ("二つの条件でOR検索をします") strFil = "[ステータス] = '" & Me.ステータスリスト & "' Or " & "[申請内容]='" & Me.申請リスト & "'" End If End If Me.Filter = strFil Me.FilterOn = True End Sub 上記はそのままです。 選択のチェックボックスにチェックを入れてもそのデータが編集画面に反映されない現象が発生してしまいました。どこが悪いのか教えて頂ければ幸いです。

  • 数値かどうかを取得したい IsNumberではダメ

    Sub Macro2() Dim mystr As String mystr = "1" If IsDate(mystr) = False Then MsgBox "NO" End If End Sub これなら日付型かどうかを取得できるのに、 Sub Macro1() Dim mystr As String mystr = "1" If IsNumber(mystr) = False Then MsgBox "NO" End If End Sub だと、IsNumberがコンパイルエラーになります。 変数に入っている値が数値として評価できるかを取得する方法を教えてください。

  • エクセル マクロ 初心者です

    エクセルマクロ初心者です。 以下の2つの Private Sub Worksheet_Change(ByVal Target As Range)を1つのシートで実行させたいのですが、 当方、初心者なので組み合わせ方が分かりません。 よろしくお願いします。 ===No1=== Private Sub Worksheet_Change(ByVal Target As Range) Application.EnableEvents = False Target = StrConv(Target, vbUpperCase) Application.EnableEvents = True End Sub ===No2=== Private Sub Worksheet_Change(ByVal Target As Range) Dim Ans As Integer If Target.Count = 1 Then Ans = MsgBox("コピーは禁止!!", vbCritical) MsgBox "データを消去します。" With Application .EnableEvents = False .Undo .EnableEvents = True End With End If If Target.Count = 1 Then Exit Sub Else MsgBox “複数セルのコピー禁止!" With Application .EnableEvents = False .Undo .EnableEvents = True End With End If End Sub ------------ 上記の2つを1つのシートで動作させたいのですが、うまくいきません。 単体では、動作します。

  • Accessフォームの作成

    Accessで作成されているシステムの ファイル取り込みフォームにある実行ボタンを押下すると、 下記のメッセージが表示されます。 「select case に対応する case がみつからない。」 どこかで指定しないといけないのでしょうか? Private Sub Cmd実行_Click() On Error GoTo Err Dim StrSql As String Dim IntNDCnt As Integer Dim IntNTCnt As Integer '確認メッセージの出力 If MsgBox("処理を開始します。よろしいですか?", vbInformation + vbYesNo, "データ取込処理") = vbNo Then Exit Sub End If '対象データ別の処理実行 Select Case Me.Cmb対象.ListIndex Case -1 'エラー MsgBox "読込むデータを指定してください", vbCritical, "データ取込処理" Exit Sub Case 0 '全データ If F_手数料明細読込() = False Then Exit Sub End If If F_奨励金読込() = False Then Exit Sub End If If F_減額読込() = False Then Exit Sub End If If F_預り金読込() = False Then Exit Sub End If Case 1 '手数料データ If F_手数料明細読込() = False Then Exit Sub End If Case 2 '奨励金データ If F_奨励金読込() = False Then Exit Sub End If Case 3 '減額データ If F_減額読込() = False Then Exit Sub Case 4 '預り金データ If F_預り金読込() = False Then Exit Sub End If End Select 今は、Case 4が黄色に反転します。

  • アクセス フォームが存在するかを一発で取得したい

    フォームが50個くらいあるのですが 該当のフォームが存在するかvbaで取得したいのですが If CurrentProject.AllForms("フォーム1").IsLoaded Then のように、一発で取得する方法はありますか? 今は Sub Sample1() Dim DB As DAO.Database Dim f As DAO.Document Set DB = CurrentDb Dim strForm As String Dim flg As Boolean strForm = "Fメインメニュー" For Each f In DB.Containers!Forms.Documents If strForm = f.Name Then flg = True Exit For End If Next If flg = False Then MsgBox strForm & "は存在しません" End If End Sub のような感じで、すべてのフォームをループしているのですが 無駄が多い気がします。 改善策があればお願いします。

  • VB.NET Form1からForm2を開いたり閉じたりする方法

    VB.NET2005でForm1にあるCheckBoxをTrueにするとform2をモードレスフォームとして開き、CheckBoxをFalseにするとform2を閉じる方法がわかりません。また、form2の[×]で閉じた時にはForm1にあるCheckBoxをFalseにする方法がわかりません。 '----------------------------------- Private Sub CheckBox2_CheckedChanged ・・・   Dim f_cnt As Integer   Dim form2 As New Form2()   f_cnt = My.Application.OpenForms.Count   If CheckBox1.Checked = True Then     If f_cnt = 1 Then form1.Show() 'モードレスフォームとして表示する   Else    form2.Close() ←閉じない   End If End Sub '-----------------------------------

  • VBAでの「メソッドまたはデータメンバが見つかりま

    word2016で以下のプログラムを流したいのですが、「メソッドまたはデータメンバが見つかりません」のエラーが出ます。 Dim CB As Variant, i As Long CB = Application.ClipboardFormats If CB(1) = True Then MsgBox ”クリップボードになにも値がありません。”,48 Exit Sub End If どうすれば直るでしょうか?よろしくお願いします。

  • キャンセルボタンをクリックしたかどうかを取得したい

    InputBoxでもしキャンセルボタンが押されたら・・・ってどうやればいいですか? Sub あああ() Dim a As String a = InputBox("文字を入れてください。") MsgBox a End Sub をした時に、キャンセルボタンをクリックしたかどうかを取得したいのですが、どうすればいいんですか? a = InputBox("文字を入れてください。") の次に Cancel = True をいれても vbCancel = True をいれてもエラーになります。 Sub あああ() Dim a As String a = InputBox("文字を入れてください。") If a = "" Then MsgBox "キャンセルが押されました" End If End Sub これだとOKでもキャンセルでもメッセージが表示されます。

  • Excelのブック間の串刺し計算について

    Excelのブック間の串刺し計算について VBA超初心者です。同じフォルダ内にファイルがいくつかあり、同じ形式で、sheet1のB4のセルに計があったとして、それをブック間で串刺し集計したいのですが、うまくいきません。どこが悪いのかもわからず、困り果ててます。ご指導お願いします。 Sub BookShuukei() Dim FileName As String Dim Total As Integer Dim OpenedBook As Workbook Dim IsBookOpen As Boolean FileName = Dir("*.xls") Application.ScreenUpdating = False Do While FileName <> "" If FileName <> ThisWorkbook.Name Then IsBookOpen = False For Each OpenedBook In Workbooks If OpenedBook.Name = FileName Then IsBookOpen = True Exit For End If Next If IsBookOpen = False Then Workbooks.Open (FileName) End If Total = Total + Workbooks(FileName).Sheets(1).Range("B4").Value If IsBookOpen = False Then Workbooks(FileName).Close End If End If FileName = Dir() Loop Application.ScreenUpdating = True MsgBox (Total) End Sub

  • CSVが文字コードUTF-8かどうかの判定

    かなりデータ量が多い(10万レコード超)CSVファイルが、100件近くあります。これをエクセルに取り込んで順次同じような作業をしようと思っています。とりあえずCSVを以下のコードで開いています。 Sub CSV入力4() 'クエリーテーブルを使ったCSV読み込みVBAコード Dim myFile As Variant myFile = Application.GetOpenFilename(FileFilter:="CSVファイル(*.csv),*.csv", Title:="CSVファイルの選択") If myFile = False Then Exit Sub End If ActiveSheet.Cells.Clear With ActiveSheet.QueryTables.Add(Connection:="text;" & myFile, Destination:=Range("A1")) ' .TextFilePlatform = 932 'Shift_Jis .TextFilePlatform = 65001 'UTF8 .TextFileCommaDelimiter = True .Refresh BackgroundQuery:=False .Delete End With MsgBox "読込完了" End Sub 問題は、CSVに拡張子で区別できないUTF-8のCSVファイルがあることです。事前にわかっていれば .TextFilePlatform = 932 'Shift_Jis .TextFilePlatform = 65001 'UTF8 の使い分けで対応できるのですが、開いてみて文字化けがあるかどうか調べないとわかりません。自動的に判定する方法はないでしょうか?

専門家に質問してみよう