C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: テキストファイルをExcelで処理するVBScript


(過去ログ 123 を表示中)

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■73662 / inTopicNo.1)  テキストファイルをExcelで処理するVBScript
  
□投稿者/ 椿こはる (1回)-(2014/10/22(Wed) 18:55:12)

分類:[VBScript] 

初めまして、よろしくお願いします。
現状、件名のようなテキストファイル(SSV)をエクセルで処理するスクリプトを組み、
一応動作させることはできたのですが、細々と問題点を残しております。
自分とグーグル先生の力だけでは解決できなかったので、
こちらで皆様のお知恵をお借りしたく存じます。

■開発環境
Windows8.1pro、コーディングにはメモ帳を利用しており、Office2013をインストール済みです。

■プログラム内容
とあるソフトか吐き出したテキストファイル(SSV)を
VBSファイルにドラッグ&ドロップすることで
Excelで開き、特定の文字列を検索し、その下の表をコピー、
あらかじめ用意したワークシートに貼り付け、
そのワークシートで行う操作のマクロを実行し、
テキストファイルと同名のExcelファイルとして保存する

コードここから
−−−−−−−−−−−−−−−−−−−
Option Explicit

If Wscript.Arguments.Count > 0 Then

Dim txtFile
Dim xlApp
Dim xlWb
Dim args
Set args = Wscript.Arguments

Set xlApp = Wscript.CreateObject("Excel.Application")
xlApp.Visible = True

For Each txtFile in args

Set xlWb = xlApp.Workbooks.Open(txtFile)
With xlWb.Worksheets(1)
.Columns("A:A").TextToColumns .Range("B1"), 1, 1, True, False, False, False,True,False
'開始位置,区切り文字,二重引用符,連続を一つに,タブ,セミコロン,コンマ,スペース,その他
.Range("A1").EntireColumn.Delete
End With

Dim objFileSys
Dim txtTitle
Set objFileSys = CreateObject("Scripting.FileSystemObject")
txtTitle = objFileSys.GetBaseName(txtFile)
Set txtFile = Nothing

Dim objEvent
Set objEvent = xlWb.Worksheets(1).Cells.Find("任意の文字列", , , , , , False,False,False)
Set objEvent = objEvent.Offset(2, 0)
Set objEvent = objEvent.CurrentRegion
Dim ELBook
Dim ELSheet
Set ELBook = xlApp.Workbooks.Open("D:\集計VBS\集計.xlsm")
'フォルダを動かしたらパスを書き換える※注意1
Set ELSheet =  ELBook.Worksheets("EventList")
objEvent.copy ELSheet.Range("A1")
ELSheet.Range("A2") = "ID"
xlApp.Run "Sheet1.set_ID"

Set objEvent = Nothing
xlWb.Close(False)
Set xlWb = Nothing

xlApp.DisplayAlerts = False
ELBook.SaveAs "D:\集計VBS\結果\"& txtTitle &".xlsx",51
xlApp.DisplayAlerts = True
'保存先の指定※注意2
Set objFileSys = Nothing
Set txtTitle = Nothing
Set ELBook = Nothing
Set ELSheet = Nothing
Next
Set args = Nothing
Set xlApp = Nothing

Else
Wscript.Echo "ファイルを選択してください"
Wscript.Quit
End If

−−−−−−−−−−−−−−−−−−−
コードここまで


■問題点
1. フォルダを動かすとパスを変更する必要がある
2. 本当はCurrentRegionではなく、「Ctrl+Shift+→」&「Ctrl+Shift+↓」を選択したい(Selectionを使用せず実装する方法が分からず)
3. 別名保存しないで複数ファイルを開きたい
(ファイルを保存する必要が無い場合もあり、単数のファイルの処理の場合のスクリプトは組めたが、45行目辺りの開いたワークブックを別名で保存する処理が無ければ、複数のファイルを処理できない)


この場にそぐわぬ初心者で、質問にも至らぬ点があるかと思いますが、
よろしくお付き合いいただければ幸甚です。

引用返信 編集キー/
■73665 / inTopicNo.2)  Re[1]: テキストファイルをExcelで処理するVBScript
□投稿者/ 魔界の仮面弁士 (156回)-(2014/10/22(Wed) 20:18:49)
No73662 (椿こはる さん) に返信
> xlWb.Close(False)
この場合は、
 xlWb.Close False
もしくは
 Call xlWb.Close(False)
と書くのが自然かと。


現状のコードだと、この括弧は
 Call xlWb.Close( (False) )
に相当する意味になりますよ。



> 1. フォルダを動かすとパスを変更する必要がある

このパスとは「※注意」のある
> Set ELBook = xlApp.Workbooks.Open("D:\集計VBS\集計.xlsm")
> ELBook.SaveAs "D:\集計VBS\結果\"& txtTitle &".xlsx",51
のことですよね。


(案1) VBScript ファイルの位置からの相対パス指定の場所に出力するようにする。
http://www.happy2-island.com/vbs/cafe02/capter00105.shtml

(案2) 基準パスを、Const でコード先頭に定義しておく。

(案3) パス指定を、レジストリや外部ファイルなどで定義するようにしておく。


> 2. 本当はCurrentRegionではなく、「Ctrl+Shift+→」&「Ctrl+Shift+↓」を選択したい(Selectionを使用せず実装する方法が分からず)
こんな感じかな。

Const xlDown = &HFFFFEFE7
Const xlToRight = &HFFFFEFBF
Set rangeTopLeft = 範囲内の左上セルのRange
Set rangeArea = rangeTopLeft.Worksheet.Range(rangeTopLeft, rangeTopLeft.End(xlToRight))
Set rangeArea = rangeTopLeft.Worksheet.Range(rangeArea, rangeTopLeft.End(xlDown))
'rangeArea.Select


> 3. 別名保存しないで複数ファイルを開きたい
ドロップした複数ファイルの情報を、一つの 集計.xlsm 内に
取りまとめたいというのであれば、こういう感じかな。


【修正前】
 For Each 〜
   :
  Set xlWb = xlApp.Workbooks.Open(txtFile)
   :
  Set ELBook = xlApp.Workbooks.Open("D:\集計VBS\集計.xlsm")
   :
  xlWb.Close False
   :
  ELBook.SaveAs 〜
   :
 Next


【修正後】
 Set ELBook = xlApp.Workbooks.Open("D:\集計VBS\集計.xlsm")
 For Each 〜
   :
  Set xlWb = xlApp.Workbooks.Open(txtFile)
   :
   :
  xlWb.Close False
   :
 Next
 ELBook.SaveAs 〜


そういう意味ではなく、集計.xlsm を複数開きたい、という意味であれば、
Workbooks.Open ではなく、Workbooks.Add を使えば OK です。
引用返信 編集キー/
■73721 / inTopicNo.3)  Re[2]: テキストファイルをExcelで処理するVBScript
□投稿者/ 椿こはる (2回)-(2014/10/24(Fri) 21:47:44)
No73665 (魔界の仮面弁士 さん) に返信

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

>>xlWb.Close(False)
> この場合は、
>  xlWb.Close False
> もしくは
>  Call xlWb.Close(False)
> と書くのが自然かと。

おお、お恥ずかしい。
10年前にJavaScriptを多少触ったことがあるのと、
高校レベルでBasicが読める程度の知識で、
エクセルVBAから安易にVBSに手を出したので、色々とボロボロで……。
値を返すか返さないかで区別すると調べて納得したつもりなのですが、
ついカッコつけたがってしまって(違)
ご指摘ありがとうございます。

>>1. フォルダを動かすとパスを変更する必要がある

> (案1) VBScript ファイルの位置からの相対パス指定の場所に出力するようにする。
> http://www.happy2-island.com/vbs/cafe02/capter00105.shtml

こちらの(案1)を使わせていただきました。
紹介して頂いたサイトは何度も訪れて参考にさせてもらっていたのですが、
FullNameは必要ないと見落としておりました。


>>2. 本当はCurrentRegionではなく、「Ctrl+Shift+→」&「Ctrl+Shift+↓」を選択したい(Selectionを使用せず実装する方法が分からず)
> こんな感じかな。
> 
> Const xlDown    = &HFFFFEFE7
> Const xlToRight = &HFFFFEFBF
> Set rangeTopLeft = 範囲内の左上セルのRange
> Set rangeArea = rangeTopLeft.Worksheet.Range(rangeTopLeft, rangeTopLeft.End(xlToRight))
> Set rangeArea = rangeTopLeft.Worksheet.Range(rangeArea, rangeTopLeft.End(xlDown))
> 'rangeArea.Select

成程!
実は、私もSelectionオブジェクトが使えないなら自分でオブジェクトを定義すればよいのではないか、
という所までは思いついたのですが、
Set rangeArea = rangeTopLeft.Range(rangeTopLeft, rangeTopLeft.End(xlToRight))
というようなWorkSheetを省いた形で記述しており、これが動かなかったため
アプローチ自体が間違っているものと勘違いしておりました。
何が間違っていたか判明してすっきりしました。

定数を使う事に少し物怖じしているので、
今回はxlDown,xlToRightにそれぞれ値をそのまま-4121,-4161を入れて利用させていただきました。
−−−−−−−−−−−−−−−−−−−
Set rangeArea = objEvent.Worksheet.Range(objEvent, objEvent.End(-4161))
Set rangeArea = objEvent.Worksheet.Range(rangeArea, objEvent.End(-4121))
……
rangeArea.copy ELSheet.Range("C3")
−−−−−−−−−−−−−−−−−−−

>>3. 別名保存しないで複数ファイルを開きたい

> そういう意味ではなく、集計.xlsm を複数開きたい、という意味であれば、
> Workbooks.Open ではなく、Workbooks.Add を使えば OK です。

こちらでした。こんな1メソッドの変更で実現できるとは!
今回もAddの指定できるテンプレートというやつが、
普通のエクセルファイルでは無理だと思いこんでいたので、
再度MSDNを何度も読み返し、
結局試しに実行してみて感動しました。

こちらに書き込む前に1箇月は悩んでいたのですが、
問題の全てがすっきりと解決し、いやはや、もう、感激です。
独学ではやはり視野狭窄になりがちだということも再認識しました。
こちらで質問させていただいて良かったです。
魔界の仮面弁士さん、
本当にありがとうございます。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -