2014/10/30

手は・・・

・・・抜くモノではナイな(;-_-)



PSO2の 予告緊急/イベントを 公式サイトの更新確認した上で取得し、Googleカレンダーへの予定投稿と、Twi予約鯖として動作させてる
Googleアカウントへのメール送信を自動投稿処理するスクリプトで、一部の時刻だけ正常処理出来ない問題を抱えたまま運用していた・・・


今回 思い切って その原因箇所を特定すべく スクリプトのフローを追いつつ修正とテストを繰り返し、11h程時間を喰ってしまった・・・


時間を掛けた分、原因はきっちり突き止めた・・・ ソレが 過去スクリプトで汎用として構成し、
今まで数々の処理で流用し、安定して結果を提供してくれていた関数だったと云うオチに絶句(;´∀`)

そもそもPSO2イベント向け用途として 初夏から組んでいる箇所は完全に機能していたので、
かえって答えに辿り着くまで時間を要してしまうと云う罠が・・・ 


・・・VBScriptは、VBA等と違って日時処理のライブラリは最小限でしかなく、且つ変数に型宣言が出来ないから、
それを補う関数を2つほど  おきつねさまは 自前で用意して流用し続けている。

その関数は、リリースが2009年で おそらくβで運用し始めてからは最低でも6~7年・・・
気まぐれで社蓄してた頃には基本を組んであったから、総じて既に10年は経過している・・・(;´Д`)

当然、今までの利用では 問題は発生していなかったので、その処理中で データを構成する際に代入した基データを
その内部処理で変更された値に上書きしてしまう構造になっていようとは・・・

で、以下赤文字部分が、加筆と ソレに伴う書き換えとなった対象箇所
    ' X3FManeger (fCopy) 
    '------------------------------------  
    ' iDT - 日時文字列 ないし 日/時配列取得 for VBScript  
    ' - Created by LazwardFox -  
    
        ' VarChk  

        ' Update 20141030 042330 代入した基データを上書きしてしまう問題を修正。 
        ' Update 20091103 1149 パラメータチェックを完全外部化。 
        ' Update 20091010 1736 文字列/シリアル値による日時指定、 
                            ' 及び パラメータ省略に対応。 
        ' Update 20090228 0458 変数宣言変更  
        ' Update 20090223 0959 時刻桁処理変更  
        ' Update 20090223 0253 Len記述忘れ修正  
        ' Update 20090223 0135 変数宣言忘れ修正  
        ' Update 20090210 0218  
        ' Update 20090210 0115  
        ' Release 20090209 2035  

        '    iDT (  
        '     {tDateTime} - Serial / DateTimeStrings (省略可、既定値 - Now)  
        '    ,{dSplitter} - DateSplitString             (省略可、既定値 - "/")  
        '    ,{dtSeparater} - Date/Time SepaleteString (省略可、既定値 - " ")  
        '    ,{tSplitter} - TimeSplitString             (省略可、既定値 - ":")  
        '    ,{Control} - 戻り値 文字列/配列指定  0 or 1    (省略可、既定値 - 1)  
        '    ,Result - 結果日時文字列    (省略不可) 
        '    )  

        ' Memo - いずれかのSplitterに ~|" を設定すると、全ての要素が、配列として返されます。 
        ' iDT ,"|",,,,arDT ' → arDT = (0) YYYY / (1) MM / (2) DD / (3) HH / (4) NN / (5) SS  

    Public Function iDT(tDateTime, dSplitter, dtSeparater, tSplitter, Control, Result)
        Dim inDateTime
        Dim vDateTime, cDateTime, nD, nS, strYMD, strHNS
        Dim dVal, cVar, arVar
        inDateTime = tDateTime
        dVal = Array(Now(), "/", " ", ":", 1) ' 既定値配列  
        cVar = Array(Array(inDateTime, 7, False, dVal(0)), Array(dSplitter, 10, True, dVal(1)), _
                Array(dtSeparater, 10, True, dVal(2)), Array(tSplitter, 10, True, dVal(3)), _
                Array(Control, 2, False, dVal(4)))
        arVar = VarChk(cVar)
        inDateTime = arVar(0)
        strYMD = FormatDateTime(DateValue(inDateTime), 0)             'Update 20091010 1736  
        nS = ":" & Split(CStr(FormatDateTime(inDateTime, 3)), ":")(2)  'Update 20090223 0951  
        strHNS =  FormatDateTime(inDateTime, 4) & nS                  'Update 20090223 0951  
        If arVar(3) = dVal(3) Then
        Else
            strHNS = Replace(strHNS, dVal(3), arVar(3))
        End If
        If arVar(1) = dVal(1) Then
        Else
            strYMD = Cstr(Replace(strYMD, dVal(1), arVar(1)))
        End If
        If arVar(4) = dVal(4) Then
            Result = Split(strYMD & "|" & strHNS,"|")
        Else
            Result = strYMD & arVar(2) & strHNS
        End If
    End Function


    ' X3FManeger (fCopy) 
    '------------------------------------  
    ' VarChk  
    ' 変数内データの確認と、既定値への置換をサポート。 
    ' 関数への代入パラメータ確認向け 
    ' - Created by LazwardFox -  

        ' Update  
        ' Release 20091103 1152  
        ' βRelease 20091103 1152  
        ' DevStart 20091103 1014  

        ' VarChk - 結果を配列で返す。 
        '        (  
        '           arVar - 調査対象と条件を配列で代入する。 [省略不可]  
        '        )  

        ' arVar = Array(Array(Value,VarTypes,Boolean,DefaultData),Array(Value,VarTypes,Boolean,DefaultData),・・・)  
        
        ' Value - 確認対象となる値、ないし変数  
        ' VarTypes - VarType定数 (日時値を得る場合は、基が文字列代入であっても 8 を指定)  
        ' Boolean - 条件の可否 
        ' DefaultData - 代替規定値 (データ型自由)  

    Function VarChk(arVar)
        On Error Resume Next
        If VarType(arVar) >= 8192 Then
            ReDim iResult(UBound(arVar))
            Dim Pc, iVar, cVar ,vVar, vDT, cDT
            Pc = 0
            For Each iVar In arVar
                cVar = VarType(iVar) >= 8192 And UBound(iVar) = 3
                If cVar Then
                    cVar = VarType(iVar(1)) = 2 And VarType(iVar(2)) = 11
                    If cVar Then
                        If iVar(1) = 8 Then
                            vDT = VarType(iVar(0))
                            cDT = vDT <> 10 And (vDT = 7 Or (vDT = 8 And IsDate(iVar(0))))
                            If cDT Then ' シリアル値/日時文字列 識別  
                                iResult(Pc) = DateValue(iVar(0)) + TimeValue(iVar(0))
                            Else
                                iResult(Pc) = iVar(3) ' Now() 
                            End If
                        Else
                            vVar = VarType(iVar(0))
                            If iVar(2) = (vVar = iVar(1)) Then
                                iResult(Pc) = iVar(3)
                            Else
                                iResult(Pc) = iVar(0)
                            End If
                        End If
                    End If
                End If
                Pc = Pc + 1
            Next
        End If
        VarChk = iResult
    End Function
・・・こんな処理、最新の開発環境等では一切要らないんだが、VBScript・・・ それも コレの基となっているモノを構成した WSH2.x時代では イチイチ手を掛けないと働いてくれなかったからなぁ(´ヘ`;) とは云え もう長いコト、関数で受けた値は 適宜加工用変数へ代入するのが当たり前になってたので、 こんな手抜き構造の関数が、運用スクリプト中に まだ残っていた事には、正直驚きを隠せなかった・・・ しかし、過去の自らの所業に、こんなにアトになって呪われようとは サスガのおきつねさまも 想像だにしてなかったカモ・・・orz p.s. 上述2ルーチンを含むスクリプトで、冒頭にある通りの処理のほか、ランダム発生した緊急を 表示される一覧された該当する数字入力だけで カレンダーへの予定セットとTweetを 同時処理させています。

0 件のコメント:

コメントを投稿