Excel VBAをJavaScriptに翻訳 その5

Excel VBAをJavaScriptに翻訳 その5:


 はじめに

前回は、VBAを字句解析する簡単なサンプルプログラムを作成しました。

今回は、VBAの構文解析する前提としてVBAの予約語を定義したいと思います。

あわせてVBA翻訳のサンプルVBAを提示します。


前提

  • OS : Windows7以上
  • PoweShellのターミナルで実行
  • VSCodeでコード編集
  • node.js環境構築済み


VBEのオブジェクトブラウザーからVBAの予約語を取り出す

VBEとはVBAを編集するためのExcelに同梱されたエディターです。

ExcelからAtl+F11で起動できます。

VBAのライブラリの定義をここから参照して予約語をまとめます。

赤丸のボタンをマウスでクリックします。


VBE.png

すべてのライブラリと表示のあるドロップボックスのリストからVBAを選択します。
VBE2.png

VBE3.png

クラスのリストボックスのCollectionを選択します。Collectionのメンバーのリストが表示されます。
VBE4.png


この内容を以下のように定義してみます。

var vba_Module_Collection = [Add, Count, Item, Remove]; 
同様にクラスのリストに含まれる、モジュールクラスEnumの各メンバーを定義したのが

以下となります。

var vba_Module_Collection = [Add, Count, Item, Remove]; 
var vba_Module_ColorConstans = [vbBlack, vbBlue, vbCyan, vbGreen, vbMagenta, vbRed,vbWhite, vbYellow]; 
var vba_Module_Constans = [vbBack, vbCr,vbCrLf, vbFormFeed, vbLf, vbNewLine, vbNullChar, vbNullString, vbObjectError, vbTab, vbVerticalTab]; 
var vba_Module_Conversion = [Cbool, CByte, Ccur, CDate, CDbl, CDec, Cint, Clng, CLngPtr, CSng, CStr, CVar, CVDate, CVErr, Error, Error$, Fix, Hex, Hex$, Int, Oct, Oct$, Str, Str$, Val]; 
var vba_Module_DateTime = [Calendar, Date, Date$, DateAdd, DateDiff, DatePart, DteSerial, DateValue, Day, Hour, Minute, Month, Now, Second, Time, Time$, Timer, TimeSerial, TimeValue, Weekday, Year]; 
var vba_Class_ErrObject = [Clear, Description, HelpContext, HelpFile, LastDllError, Number, Raise, Source]; 
var vba_Module_FileSystem = [ChrDir, ChrDrive, CurDrive, CurDir, CurDir$, Dir, EOF, FileAttr, FileCopy, FileDateTime, FileLen, GetAttr, Kill, Loc, LOF, MkDir, Reset, RmDir, Seek, SetAttr]; 
var vba_Class_Financial = [DDB, FV, Ipmt, IRR, MIRR, NPer, NPV, Pmt, PPmt, PV, Rate, SLN, SYD]; 
var vba_Enum_FromShowConstants = [vbModal, vbModeless]; 
var vba_Class_Global = [Load, Unload, UserForms]; 
var vba_Module_Information = [Err, IMEState, IsArray, IsDate, IsEmpty, IsError, IsMissing, IsNull, IsNumeric, IsObject, QBClor, RGB, TypeName, VarType]; 
var vba_Module_Interaction = [AppActivate, Beep, CallByName, Choose, Command, Command$,CreateObject, DeleteSetting, DoEvents, Environ, Environ$, GetAllSettings, GetObject, GetSetting, IIF, InputBox, MsgBox, Patition, SaveSetting, SendKeys, Shell, Switch]; 
var vba_Module_KeyCodeConstants = [vbKey0, vbKey1, vbKey2, vbKey3, vbKey4, vbKey5, vbKey6, vbKey7, vbKey8, vbKey9, vbKeyA, vbKeyAdd, vbKeyB, vbKeyBack, vbKeyC, vbKeyCancel, vbKeyCapital, vbKeyClear, vbKeyControl, vbKeyD, vbKeyDecimal, vbKeyDelete, vbKeyDivide, vbKeyDown, vbKeyE, vbKeyEnd, vbKeyEscape, vbKeyExecute, vbKeyF, vbKeyF1, vbKeyF10, vbKeyF11, vbKeyF12, vbKeyF13, vbKeyF14, vbKeyF15, vbKeyF16, vbKeyF2, vbKeyF3, vbKeyF4, vbKeyF5, vbKeyF6, vbKeyF7, vbKeyF8, vbKeyF9, vbKeyG, vbKeyH, vbKeyHelp, vbKeyHome, vbKeyI, vbKeyInsert, vbKeyJ, vbKeyK, vbKeyL, vbKeyLButton, vbKeyLeft, vbKeyM, vbKeyMButton, vbKeyMenu, vbKeyMultiply, vbKeyN, vbKeyNumLock, vbKeyNumpad0, vbKeynumpad1,vbKeynumpad2, vbKeynumpad3, vbKeynumpad4, vbKeynumpad5, vbKeynumpad6, vbKeynumpad7, vbKeynumpad8, vbKeynumpad9, vbKeyO, vbKeyP, vbKeyPageDown, vbKeyPageUp, vbKeyPause, vbKeyPrint, vbKeyQ, vbKeyR, vbKeyRButton, vbKeyReturn, vbKeyRight, vbKeyS, vbKeySelect, vbKeySeparator, vbKeyShift, vbKeySnapshot, vbKeySpace, vbKeySubtract, vbKeyT, vbKeyTab, vbKeyU, vbKeyUp, vbKeyV, vbKeyW, vbKeyX, vbKeyY, vbKeyZ]; 
var vba_Module_Math = [Abs, Atn, Cos, Exp, Log, Randomize, Rnd, Round, Sgn, Sin, Sqr, Tan]; 
var vba_Module_Strings = [Asc, AscB, AscW, Chr, Chr$, ChrB, ChrB$, ChrW, ChrW$, Filter, Format, Format$, FormatCurrncy, FormatDateTime, FormatNumber, FormatPercent, InStr, InStrB, InStrRev, join, LCase, LCase$, Left, Left$, LeftB, LeftB$, Len, LenB, LTrim, LTrim$, Mid, Mid$, MidB, MidB$, MonthName, Replace, Right, Right$, RightB, RightB$, RTrim, RTrim$, Space, Space$, Split, StrComp, StrConv, String, String$, StrReverse, Trim, Trim$, UCase, UCase$, WeekdayName]; 
var vba_Module_SystemColorConstants = [vb3DDKShadow, vb3DFace, vb3DHighlight, vb3DLight, vb3DShadow, vbActiveBorder, vbActiveTitleBar, vbApplicationWorkspace, vbButtonFace, vbButtonShadow, vbButtonText, vbDesktop, vbGrayText, vbHiglight, vbHiglightText, vbInactiveBorder, vbInactiveCaptionText, vbInactiveTitleBar, vbInfoBackground, vbInfoText, vbMenuBar, vbMenuText, vbMsgBox, vbMsgBoxText, vbScrollBars, vbTitleBarText, vbWindowBackground, vbWindowFrame, vbWindowText]; 
var vba_Enum_vbAppWinStyle = [vbHide, vbMaximizedFocus, vbMinimizedFocus, vbMinimizedNoFocus, vbNormalFocus, vbNormalNoFocus]; 
var vba_Enum_vbCalendar = [vbCalGreg, vbCalHijri]; 
var vba_Enum_vbCallType = [vbGet, vbLet, vbMethod, vbSet]; 
var vba_Enum_vbComperMrthod = [vbBinaryCompare, vbDatabaseCompare, vbTextCompare]; 
var vba_Enum_vbDateTimeFormat = [vbGreneralDate, vbLongDate, vbLongTime, vbShortDate, vbShortTime]; 
var vba_Enum_vbDayOfWeek = [vbFriday, vbMonday, vbSturday, vbSunday, vbThursday,vbTuesday,vbUseSystemDayOfWeek, vbWendnesday]; 
var vba_Enum_vbFileAttribute = [vbAlias, vbArchive, vbDirectory, vbHidden, vbNormal, vbReadOnly, vbSystem, vbVolume]; 
var vba_Enum_vbFirstWeekOfYear = [vbFirstFourDays, vbFirstFullWeek, vbFirstJan1, vbUseSystem]; 
var vba_Enum_vbIMEStatus = [vbIMEAlphaDbl, vbIMEAlphaSng, vbIMEDisable, vbIMEHiragana, vbIMEKatakanaDbl, vbIMEKatakanaSng, vbIMEModeAlpha, vbIMEModeAlphaFull, vbIMEModeDisable, vbIMEModeHangul, vbIMEModeHangulFull, vbIMEModeHiragana, vbIMEModeKatakana, vbIMEModeKatakanaHalf, vbIMEModeNoControl, vbIMENodeOff, vbIMENodeOn, vbIMENoOp, vbIMEOff, vbIMEOn]; 
var vba_Enum_vbMsgBoxResult = [vbAbout, vbCancel, vbIgnore, vbNo, vbOK, vbRetry, vbYes] 
var vba_Enum_vbMsgBoxStyle = [vbAboortRetryIgnore, vbApplicationModal, vbCritical, vbDefaultButton1, vbDefaultButton2, vbDefaultButton3, vbDefaultButton4, vbExclamation, vbInformation, vbMsgBoxHelpButton, vbMsgBoxRight, vbMsgBoxRtlReading, vbMsgBoxSerForeground, vbOKCancel, vbOKOnly, vbQuestion, vbRetryCancel, vbSystemModal, vbYesNo,vbYesNoCancel]; 
var vba_Enum_vbQueryClose = [vbAppTaskManager, vbAPPWindows, vbFormCode, vbFormControlMenu, vbFormMDIForm]; 
var vba_Enum_vbStrConv = [vbFormUnicode, vbHiragana, vbKatakana, vbLowerCase, vbNorrow, vbProperCase, vbUnicode, vbUpperCase, vbWide]; 
var vba_Enum_vbTriState = [vbFalse, vbTrue, vbUseDefault]; 
var vba_Enum_vbVarType = [vbArray, vbBoolean, vbByte, vbCurrency, vbDataObject, vbDate, vbDecimal, vbDouble, vbEmpty, vbError, vbInteger, vbLong, vbNull, vbObject, vbSingle, vbUserDifinedType, vbVariant]; 


オブジェクトライブラリ以外の予約語

VBAを構成する構文解析で登場するキーワードをざっくりと定義します。

もちろん上記のVBAオブジェクトライブラリ定義以外となります。

悪戦苦闘で以下のように定義しました。(最終的には完結予定)

// 予約語 
var vba_reserved_word = [ 
        AddressOfAnd, Any, Array, As, Attribute, Append, 
        Base, Binary, Boolean, ByRef, Byte, ByVal, 
        Call, Case, Circle, Close, Compare, Const, 
        Debug, Decimal, Declare, DefBool, DefByte, DefCur,  
        DefDate, DefDbl, DefDec, DefInt, DefLng, DefLngLng,  
        DefLngPtr, DefObj, DefSng, DefStr, DefVar, Dim, Do, Double, 
        Each, Else, ElseIf, Empty, End, EndIf, Enum, Eqv, Erase,  
        Event, Exit, Explicit, 
        FALSE, For, Friend, Function, 
        Get, Global, GoSub, GoTo, 
        If, Imp, Implements, In, Input, InputB, Integer, Is, 
        Lbound, Let, Like, LINEINPUT, Lock, Long, LongLong,  
        LongPtr, Loop, Lset, 
        Me, Mod, 
        New, Next, Not, Nothing, Null, 
        On, Open, Option, Optional, Or, Output, 
        ParamArray, Preserve, Print, Private, Property, PSet,  
        Public, Put, 
        Random, RaiseEvent, ReDim, Rem, Resume, Return, Rset, 
        Scale, Selec, Set, Shared, Single, Spc, Static, Step, Stop, Sub, 
        Tab, Then, To, TRUE, Type, TypeOf, 
        Ubound, Unlock, Until, 
        Variant, VB_Base, VB_Control, VB_Creatable, VB_Customizable, 
        VB_Description, VB_Exposed, VB_Ext_KEY, VB_GlobalNameSpace,  
        VB_HelpID, VB_Invoke_Func, VB_Invoke_Property, VB_Invoke_PropertyPut, 
        VB_Invoke_PropertyPutRef, VB_MemberFlags, VB_Name, VB_PredeclaredId, 
        VB_ProcData, VB_TemplateDerived, VB_UserMemId, VB_VarDescription, 
        VB_VarHelpID, VB_VarMemberFlags, VB_VarProcData, VB_VarUserMemId, 
        Wend, While, With, WithEvents, Write, 
        Xor 
];         
// VBA演算子         
var vba_operator = ["+", "-", "*", "/", "\", "^"]; 
// VBA比較演算子 
var vba_comparison_operator = ["<", "<=", ">", ">=", "=", "<>"]; 


予約語について

VBAで登場する予約語をまとめました。

たぶん抜けや誤字・脱字がありそうです。調整しながら進んでいきます。


最初のExcelと翻訳対象VBAコード

構文解析ロジックを組み立てる上で元になるExcelとVBAのサンプルを用意します。

これを最初にJavaScriptへ翻訳して構文解析ロジックの正規化を図りたいと思います。


問題集を作るExcel


① 元文

問題のテキスト(wikiなどからコピペ)。

穴埋め問題にしたいテキストを赤文字に変更します。


②問題

(A,6)セルに=AnzColor(A1,3)を入力します。

※カラーインデックス=3は赤

関数 引数 機能
AnzColor セルアドレス、カラーインデックス 元文の指定したカラー文字を□に置換します


③解答

(A,8)セルに=AnsColor(A1,3)を入力します。

※カラーインデックス=3は赤

関数 引数 機能
AnsColor セルアドレス、カラーインデックス 元文の指定したカラー文字を抽出します


VBE5.png



問題集を作るVBAコード

' 
' 特定範囲の文字色を判定し、□に変更して返す 
' adrs : Cell 
' clr  : ColorIndex 
' 
Function AnzColor(adrs, clr) As String 
 
    Dim iLen    As Integer 
    Dim ix      As Integer 
    Dim Buf     As String 
 
    Sheets("Question").Select 
 
    Buf = "" 
    For Each ad In adrs 
        iLen = Len(ad) 
        For ix = 1 To iLen 
 
            ' 指定した色の場合 
            If ad.Characters(ix, 1).Font.ColorIndex = clr Then 
                Buf = Buf & "□" 
            Else 
                Buf = Buf & Mid(ad, ix, 1) 
            End If 
        Next ix 
    Next 
 
    AnzColor = Buf 
 
End Function 
 
' 
' 特定範囲の文字色を判定し、文字色に一致する文字列群を返す 
' adrs : Cell 
' clr  : ColorIndex 
' 
Function AnsColor(adrs, clr) As String 
 
    Dim iLen    As Integer 
    Dim ix      As Integer 
    Dim Buf     As String 
    Dim sw      As Boolean 
 
    Sheets("Question").Select 
    Buf = "" 
    sw = True 
 
    For Each ad In adrs 
        iLen = Len(ad) 
        For ix = 1 To iLen 
 
            ' 指定した色の場合 
            If ad.Characters(ix, 1).Font.ColorIndex = clr Then 
                Buf = Buf & IIf(sw = False, ",", "") & Mid(ad, ix, 1) 
                sw = True 
            Else 
                sw = False 
            End If 
        Next ix 
    Next 
 
    AnsColor = IIf(Left(Buf, 1) = ",", Mid(Buf, 2), Buf) 
 
End Function 


まとめ

ばたばたと予約語と翻訳対象のVBAを作成しました。

途中で路線変更しそうな予感です。

このあたりが一番退屈なところかもしれません。

予約語はこんな感じぐらいで認識しましょう。

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)