人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

あるテキストファイルに設定を追加するVBScriptの作成を考えております。


?※ポイントは基本的にベストアンサーの方にすべて配分させていただきますが、内容によりその他の方にも配分します。


以下のような構成のテキストファイルがあり、セクション毎(<1TEST1>等)の設定項目(DATA1)に値を追加する
VBScriptの作成を考えております。以下2点の仕様に対応するVBScriptのサンプルスクリプトを作成いただけないしょうか
よろしくお願いいたします。


??設定する際の注意点として、セクション毎(<1TEST1>等)に設定項目(DATA1)を上から精査し、
? ?設定が入力されていない部分(「<1TEST1>」であれば「DATA4 = 」)に設定を追加したいです。

??また、追記する際に「DATA4 = 」及び「DATA5 = 」の項目が既に別の値が入力されていた場合は「DATA6 = 」を追加して
? 設定を追加するようなものにしたいです。


仕様の?、?の例につきましてはコメントに書かせていただきます。

●質問者: gocnia3
●カテゴリ:コンピュータ インターネット
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● Mook
●2000ポイント ベストアンサー

一応書かれている仕様は網羅していると思いますが、
過不足があれば、コメントと下さい。

実行方法は VBS ファイルに二つのデータファイルをドロップするか、
コマンドで

>CScript AppendData.vbs data.txt append.dat

として実行してください。

??????????????????????????????????????
改訂版です。

以下変更しました
先頭に書かれたセクションをマスター位置として、指定しています。

想定データです。
元データ:data.txt

<1TEST1> 'セクション1

<2TEST2> 'セクション1
DATA1 = GGG1
DATA2 = GGG2
DATA3 = GGG3
DATA4 = GGG9
DATA5 = 

<3TEST3> 'セクション1
DATA1 = FFF1
DATA2 = FFF2
DATA3 = FFF3
DATA4 = FFF9


追加データ:append.dat

<2TEST2> <= MASTER_2用追加データ
<1TEST1> <= 1用追加データ
<3TEST3> <= 3用追加データ


スクリプト:AppendData.vbs

'================================================================
'// *.txt[ SourceFileExtention で拡張子を設定] ファイルに
'// *.dat[ AppendFileExtention で拡張子を設定] ファイルの内容を追加する
'---------------------------------------------------------------
'// *.dat[設定可能] の書式は
'//     <セクション名1> <= データ1 先頭で記述したセクションが主データ
'//     <セクション名2> <= データ2
'//     <セクション名3> <= データ3
'---------------------------------------------------------------
'// 結果は元のファイルに時間情報をつけた次のファイル名として保存する
'//    元ファイル名_YYYYMMDD_HHMMSS.txt
'---------------------------------------------------------------
'// 改定:先頭で指定したセクションと同じ位置に全体を設定するよう変更
'//    設定先が空で無い場合はエラー
'================================================================
Option Explicit

'--------------------------------------------------
'★ ユーザー設定 (1) :処理データの拡張子 (小文字で指定)
'--------------------------------------------------
Public Const SourceFileExtention = "txt"

'--------------------------------------------------
'★ ユーザー設定 (2) :設定データの拡張子 (小文字で指定)
'--------------------------------------------------
Public Const AppendFileExtention = "dat"

'---------------------------------------------------------------
Public Const AD_QUIET = 0  ' メッセージを出さない
Public Const AD_ERROR = 1  ' エラーのみ表示
Public Const AD_INFO = 3  ' すべての処理を表示

Public LogLevel

'--------------------------------------------------
'★ ユーザー設定 (3) :実行時のメッセージ出力レベル
'--------------------------------------------------
LogLevel = AD_INFO

Public LogText
LogText = ""

'---------------------------------------------------------------
Public fso
Set fso = CreateObject("Scripting.FileSystemObject")

'---------------------------------------------------------------
' 処理開始
'---------------------------------------------------------------
 Call Main()
 If LogLevel <> AD_QUIET And Len( LogText ) > 0 Then WScript.Echo LogText
 WScript.Quit

'---------------------------------------------------------------
Sub Main()
'---------------------------------------------------------------
 Dim sourceFilePath
 sourceFilePath = ""

 Dim dataFilePath
 dataFilePath = ""

  '// 引数処理
 Dim i
 With WScript.Arguments
 For i=0 To WScript.Arguments.Count - 1
 If fso.FileExists( .Item(i) ) = False Then
 writeLog AD_ERROR, .Item(i) & "がありません。"
 Exit Sub
 Else
 Select Case LCase( fso.GetExtensionName( .Item(i) ) )
 Case SourceFileExtention
 If sourceFilePath <> "" Then
 writeLog AD_ERROR, "変更ファイルは複数指定できません。"
 Exit Sub
 Else
 sourceFilePath = .Item(i)
 End If
 Case AppendFileExtention
 If dataFilePath <> "" Then
 writeLog AD_ERROR, "データファイルは複数指定できません。"
 Exit Sub
 Else
 dataFilePath = .Item(i)
 End If
 Case Else
 writeLog AD_ERROR, "処理できない拡張子です。"
 Exit Sub
 End Select
 End If
 Next
 End With

 If sourceFilePath = "" Or dataFilePath = "" Then
 writeLog AD_ERROR, "変更ファイル(*." & SourceFileExtention & ") と データファイル(*." & AppendFileExtention & ")を指定してください。"
 Exit Sub
 End If

'// ファイル処理
 Dim sourceLines
 sourceLines = Split( fso.OpenTextFile( sourceFilePath ).ReadAll(), vbNewLine )

 Dim dataLines
 dataLines = Split( fso.OpenTextFile( dataFilePath ).ReadAll(), vbNewLine )

 Dim dataLine
 Dim dataNum
 dataNum = 0
 For Each dataLine In dataLines
 If InStr( dataLine, "<=" ) > 0 Then
 dataNum = AppendData( sourceLines, dataLine, dataNum )
 End If
 If dataNum < 0 Then Exit Sub
 Next

 Dim nowDateTime
 nowDateTime = FormatDateTime( Now(), 0 )
 nowDateTime = Replace( nowDateTime, "/", "" )
 nowDateTime = Replace( nowDateTime, ":", "" )
 nowDateTime = Replace( nowDateTime, " ", "_" )
 With fso.CreateTextFile( Left( sourceFilePath, Len(sourceFilePath) - 4 ) & "_" & nowDateTime & "." & sourceFileExtention )
 .Write Join( sourceLines, vbNewLine )
 End With

End Sub

'---------------------------------------------------------------
Function AppendData( sourceLines, dataLine, dataNum )
'---------------------------------------------------------------
 Dim apDataSet
 apDataSet = Split( dataLine, "<=" )

 Dim sectionName
 Dim sectionData
 sectionName = Trim( apDataSet(0) )
 sectionData = Trim( apDataSet(1) )

 Dim findFlag
'// セクション検索
 findFlag = False

 Dim i
 Dim dstLine
 For i=LBound( sourceLines ) To UBound( sourceLines )
 If InStr( Trim( sourceLines(i) ) ,sectionName ) = 1 Then
 dstLine = i
 findFlag = True
 Exit For
 End If
 Next
 If findFlag = False Then
 writeLog AD_ERROR, "セクション " & sectionName & " がありませんでした。"
 AppendData = -1
 Exit Function
 End If

 Dim j
 Dim num
 Dim tmpLine
 If dataNum = 0 Then
'// 主データ処理
 For j = i + 1 To UBound( sourceLines )
  '// 空データライン検索
  '// セクション内の空き DATA=
 If InStr( sourceLines(j), "DATA" ) > 0 Then dstLine = j

 If Right( Trim( sourceLines(j) ), 1 ) = "=" Then
 writeLog AD_INFO, "セクション " & sectionName & " に " & sourceLines(j) & " " & sectionData & "を設定します。"
 sourceLines(j) = Trim( sourceLines(j) ) & " " & sectionData
 AppendData = getDataNumber( sourceLines(j) )
 Exit Function
 End If

 If InStr( sourceLines(j), "<" ) = 1 Then Exit For
 Next

 If InStr( sourceLines( dstLine ), "DATA" ) > 0 Then
  '// セクション内に空き DATAnn = が無い
 num = getDataNumber( sourceLines(dstLine) ) + 1
 Else
  '// セクション内に DATAnn = が無い
 num = 1
 End If
 writeLog AD_INFO, "セクション " & sectionName & " に DATA" & num & " = " & sectionData & " を追加します。"
 sourceLines(dstLine) = sourceLines(dstLine) & vbNewLine & "DATA" & num & " = " & sectionData
 sourceLines = Split( Join( sourceLines, vbNewLine ), vbNewLine )
 AppendData = num
 Else
'// 従データ処理
  '// 空データライン検索
 For j = i + 1 To UBound( sourceLines )
  '// セクション内の空き DATA=
 If InStr( sourceLines(j), "DATA" ) > 0 Then
 If getDataNumber( sourceLines(j) ) = dataNum Then
 tmpLine = Trim( sourceLines(j) )
 If Right( tmpLine, 1 ) = "=" Then
 writeLog AD_INFO, "セクション " & sectionName & " に DATA" & dataNum & " = " & sectionData & " を追加します。"
 sourceLines(j) = tmpLine & " " & sectionData
 Else
 writeLog AD_ERROR, "セクション " & sectionName & " の DATA" & dataNum & " は既に設定されています。"
 AppendData = -1
 End If
 Exit Function
 End If
 dstLine = j
 End If
 If InStr( sourceLines(j), "<" ) = 1 Then Exit For
 Next

 Dim stNum
 If InStr( sourceLines( dstLine ), "DATA" ) > 0 Then
 stNum = getDataNumber( sourceLines(dstLine) ) + 1
 Else
 stNum = 1
 End If

 For j = stNum To dataNum - 1
 writeLog AD_INFO, "セクション " & sectionName & " に DATA" & num & " を追加します。"
 sourceLines(dstLine) = sourceLines(dstLine) & vbNewLine & "DATA" & j & " ="
 Next
 writeLog AD_INFO, "セクション " & sectionName & " に DATA" & dataNum & " = " & sectionData & " を追加します。"
 sourceLines(dstLine) = sourceLines(dstLine) & vbNewLine & "DATA" & dataNum & " = " & sectionData
 sourceLines = Split( Join( sourceLines, vbNewLine ), vbNewLine )
 AppendData = dataNum
 End If
End Function

'---------------------------------------------------------------
Function getDataNumber( strData )
'---------------------------------------------------------------
 Dim retNum

 If InStr( strData, "=" ) Then
 retNum = Split( strData, "=" )(0)
 Else
 retNum = strData
 End If

 retNum = Trim( Replace( retNum, "DATA", "" ) )
 If IsNumeric( retNum ) Then
 getDataNumber = CLng( retNum )
 Else
 getDataNumber = -1
 End If
End Function

'---------------------------------------------------------------
Sub writeLog( msgLevel, msg )
'---------------------------------------------------------------
 Select Case LogLevel
 Case AD_INFO
 If msgLevel = AD_ERROR Then
 LogText = LogText & "[ERROR !!] " & msg & vbNewLine
 Else
 LogText = LogText & msg & vbNewLine
 End If
 Case AD_ERROR
 If msgLevel = AD_ERROR Then
 LogText = LogText & "[ERROR !!] " & msg & vbNewLine
 End If
 End Select
End Sub

Mookさんのコメント
コードを少し整理し、出力の機能をレベル設定できるようにしました。

gocnia3さんのコメント
すみません。回答遅くなりました 想定通りの動きです ベストアンサーをありがとうございます 少し中身の動きを確認してます(いまやっとセクションの空白処理の確認が終わったとこです) 終わったあとに少し確認させて下さい(^ ^)

gocnia3さんのコメント
すみません。 ポイントを2倍にさせていただきますので、以下仕様に変更頂けませんか ?・特定の一つのセクションに今までの仕様通りに設定を追加してその追加方法を ? ?記憶し、その他のセクションについても同様の方法で追加します。 ? ?例としては以下となります。 ■特定のセクション ・セクション<2TEST2> ■追加したい設定項目 ・セクション<2TEST2>の行下にある設定項目の空きに「HHH9」を追加する。←★ここは一緒 ・セクション<1TEST1>の行下にある設定項目にセクション<2TEST2>でいれた箇所と同じ場所に「GGG9」を追加する。 ←★ここが変更点 ・セクション<3TEST3>の行下にある設定項目にセクション<2TEST2>をいれた箇所と同じ場所に「FFF9」を追加する。 ←★ここが変更点 ★★★★★★★例?★★★★★★★ ■テキストファイルの中身(ソースファイル) -----ここから----- <1TEST1> 'セクション1 DATA1 = GGG1 DATA2 = GGG2 DATA3 =? DATA4 = DATA5 = <2TEST2> 'セクション1 DATA1 = HHH1 DATA2 = HHH2 DATA3 = HHH3 DATA4 = DATA5 = <3TEST3> 'セクション1 DATA1 = FFF1 DATA2 =? DATA3 =? DATA4 = DATA5 = -----ここまで----- ■実行後のテキストファイルの中身 -----ここから----- <1TEST1> 'セクション1 DATA1 = GGG1 DATA2 = GGG2 DATA3 =? DATA4 = GGG9 DATA5 = <2TEST2> 'セクション1 DATA1 = HHH1 DATA2 = HHH2 DATA3 = HHH3 DATA4 = HHH9 DATA5 = <3TEST3> 'セクション1 DATA1 = FFF1 DATA2 =? DATA3 =? DATA4 = FFF9 DATA5 = -----ここまで----- ★★★★★★★例?★★★★★★★ ■テキストファイルの中身(ソースファイル) -----ここから----- <1TEST1> 'セクション1 DATA1 = GGG1 DATA2 = GGG2 DATA3 = GGG3 DATA4 = DATA5 = <2TEST2> 'セクション1 DATA1 = HHH1 DATA2 = HHH2 DATA3 = HHH3 DATA4 = HHH4 DATA5 = HHH5 <3TEST3> 'セクション1 DATA1 = FFF1 DATA2 = FFF2 DATA3 = FFF3 DATA4 = DATA5 = -----ここまで----- ■実行後のテキストファイルの中身 -----ここから----- <1TEST1> 'セクション1 DATA1 = GGG1 DATA2 = GGG2 DATA3 = GGG3 DATA4 = DATA5 = DATA6 = GGG9 <2TEST2> 'セクション1 DATA1 = HHH1 DATA2 = HHH2 DATA3 = HHH3 DATA4 = HHH4 DATA5 = HHH5 DATA6 = HHH9 <3TEST3> 'セクション1 DATA1 = FFF1 DATA2 = FFF2 DATA3 = FFF3 DATA4 = DATA5 = DATA6 = FFF9

Mookさんのコメント
確認ですけれども、一度に追加するデータは 各セクション(<#TEST#> をセクションと呼んでいますが正しいですか?) に対して同時に設定するワンセットだけとなりますか? つまり、同じセクションに対して複数を同時に登録することが無いか? ということになります。 ある場合、どれがセット(DATA# を同じところにするか)の紐付けの 仕組みが必要となりますが、それは必要ですか? つまり、追加データとして、 ?????????????????????? <1TEST1> <= GGG-1 <2TEST2> <= HHH-1 <2TEST2> <= HHH-2 <3TEST3> <= FFF-1 <3TEST3> <= FFF-2 <3TEST3> <= FFF-3 ?????????????????????? のようなケースが無いか、ということです。 仕様確認できましたら、夜にでも対応します。

Mookさんのコメント
2TEST2 と指定していますが、 結局DATA の番号は3つのセクションの中で、3箇所とも空きのある 最小の番号となると思いますが、その認識でよいですか?

gocnia3さんのコメント
>確認ですけれども、一度に追加するデータは >各セクション(<#TEST#> をセクションと呼んでいますが正しいですか?) >に対して同時に設定するワンセットだけとなりますか? その認識であってます。 同じセクションに対して複数を同時に登録することはありません。 >2TEST2 と指定していますが、 >結局DATA の番号は3つのセクションの中で、3箇所とも空きのある >最小の番号となると思いますが、その認識でよいですか? ちょっと違います。 例1として <2TEST2>で空きの合る「DATA4 =」に設定をした場合 その他のセッションでも「DATA4 =」に設定します。 その他のセッションへの追加の際に空きがあるかは関係なしに追加していただいて問題ないです。 (キーセクションに値が入っていればその他セクションにも値も入っていない仕様のため) 例2として <2TEST2>で空きがないために「DATA6 =」を追加して設定をした場合 その他のセッションでも「DATA6 =」を追加して設定します。 その他のセッションにまだ入力されてない空きがあっても「DATA6 =」を作成して入れます。

Mookさんのコメント
確認です。 2TEST2 を基準にするという指定があった場合、 2TEST2 で DATA4 が設定場所であった場合、他のセクションは (1)DATA4 が既に有っても(無いという想定ですが)、置き換えてよいですか? それともエラー終了したほうが良いですか? (2)DATA1 までしかなかった場合、DATA2、DATA3 はスキップして DATA1 = 既存設定項目 DATA4 = 設定項目 としますか、それとも補完して DATA1 = 既存設定項目 DATA2 = DATA3 = DATA4 = 設定項目 のようにしますか? (3)再度の確認ですが、一度の登録ではデータはワンセットのみで 複数あっても 2つ以降は無視する(あるいはエラー終了する) という仕様でもよいですか?

gocnia3さんのコメント
>(1)DATA4 が既に有っても(無いという想定ですが)、置き換えてよいですか? > それともエラー終了したほうが良いですか? エラー終了でお願いします。 >(2)DATA1 までしかなかった場合、DATA2、DATA3 はスキップして… 補完をお願いします。 >(3)再度の確認ですが、一度の登録ではデータはワンセットのみで… エラー終了で問題ありません。

gocnia3さんのコメント
すみません。 作成途中でも構わないので、頂けないでしょうか 宜しくお願いします。

Mookさんのコメント
複数データの判定部分は未対応ですが、 お急ぎのようでしたので更新します。 先頭セクションの位置を全体に反映します。

Mookさんのコメント
考えてみたら、 同じセクションが複数あったら、結果的にエラーになるので、 判定処理は不要のようです。 挙動に問題がなければ、これが最終版となります。

gocnia3さんのコメント
ありがとうございます。 以前作っていただいたものを改変して自分で作ってみました。 しかしやっぱり整理されているものは違いますね笑 正直ソースを読んで、調べながら理解できても、作っていただいたようなものを自分で作成できる気がしません笑(特に配列の処理の仕方など)。やはり勉強あるのみなんですかね ここまで作っていただきありがとうございました。 じっくり時間をかけて読ませていただきます。 ありがとうございました。

Mookさんのコメント
要望されていたことはできたでしょうか。 多くのポイントありがとうございました。 中身を見ようと思っていただけて、こちらも嬉しく思います。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ