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



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


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


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

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


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

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2012/03/22 20:03:55
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:Mook No.1

回答回数1314ベストアンサー獲得回数393

ポイント2000pt

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

実行方法は 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
他11件のコメントを見る
id:gocnia3

ありがとうございます。
以前作っていただいたものを改変して自分で作ってみました。

しかしやっぱり整理されているものは違いますね笑

正直ソースを読んで、調べながら理解できても、作っていただいたようなものを自分で作成できる気がしません笑(特に配列の処理の仕方など)。やはり勉強あるのみなんですかね

ここまで作っていただきありがとうございました。
じっくり時間をかけて読ませていただきます。

ありがとうございました。

2012/03/22 20:02:56
id:Mook

要望されていたことはできたでしょうか。
多くのポイントありがとうございました。

中身を見ようと思っていただけて、こちらも嬉しく思います。

2012/03/22 23:15:52
  • id:gocnia3
    ★①の例


    ■テキストファイルの中身(ソースファイル)

    -----ここから-----

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

    <2TEST2> 'セクション1
    DATA1 = HHH1
    DATA2 = HHH2
    DATA3 = HHH3
    DATA4 =
    DATA5 =

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

    -----ここまで-----

    ※テキストファイルの構成として「<1TEST1>」といったセクションの後に連番で「DATA1」「DATA2」…と設定項目
    が並んでおり、さらに「<2TEST2>」といったセクションが並んでおります。





    ■追加したい設定項目

    ・セクション<1TEST1>の行下にある設定項目の空き(上の例で言うところのDATA4 =の部分)に「GGG9」を追加する。
    ・セクション<2TEST2>の行下にある設定項目の空き(上の例で言うところのDATA4 =の部分)に「HHH9」を追加する。
    ・セクション<3TEST3>の行下にある設定項目の空き(上の例で言うところのDATA4 =の部分)に「FFF9」を追加する。

    ※設定後は以下のようになります。

    -----ここから-----

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

    <2TEST2> 'セクション1
    DATA1 = HHH1
    DATA2 = HHH2
    DATA3 = HHH3
    DATA4 = HHH9
    DATA5 =

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

    -----ここまで-----



    ★②の例



    ■テキストファイルの中身(ソースファイル)

    -----ここから-----

    <1TEST1> 'セクション1
    DATA1 = GGG1
    DATA2 = GGG2
    DATA3 = GGG3
    DATA4 = GGG4
    DATA5 = GGG5

    <2TEST2> 'セクション1
    DATA1 = HHH1
    DATA2 = HHH2
    DATA3 = HHH3
    DATA4 = HHH4
    DATA5 = HHH5

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

    -----ここまで-----


    ■追加したい設定項目

    ・セクション<1TEST1>の行下にある設定項目の空きに「GGG9」を追加する。※空きがない場合は行を追加する(DATA6を追加する)
    ・セクション<2TEST2>の行下にある設定項目の空きに「HHH9」を追加する。※空きがない場合は行を追加する(DATA6を追加する)
    ・セクション<3TEST3>の行下にある設定項目の空きに「FFF9」を追加する。※空きがない場合は行を追加する(DATA6を追加する)

    ※設定後は以下のようになります。

    -----ここから-----

    <1TEST1> 'セクション1
    DATA1 = GGG1
    DATA2 = GGG2
    DATA3 = GGG3
    DATA4 = GGG4
    DATA5 = GGG5
    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 = FFF4
    DATA5 = FFF5
    DATA6 = FFF9

    -----ここまで-----

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません