Excel VBAをJavaScriptに翻訳 その5
Excel VBAをJavaScriptに翻訳 その5:
前回は、VBAを字句解析する簡単なサンプルプログラムを作成しました。
今回は、VBAの構文解析する前提としてVBAの予約語を定義したいと思います。
あわせてVBA翻訳のサンプルVBAを提示します。
VBEとはVBAを編集するためのExcelに同梱されたエディターです。
ExcelからAtl+F11で起動できます。
VBAのライブラリの定義をここから参照して予約語をまとめます。
赤丸のボタンをマウスでクリックします。
すべてのライブラリと表示のあるドロップボックスのリストからVBAを選択します。
クラスのリストボックスのCollectionを選択します。Collectionのメンバーのリストが表示されます。
この内容を以下のように定義してみます。
同様にクラスのリストに含まれる、モジュール、クラス、Enumの各メンバーを定義したのが
以下となります。
VBAを構成する構文解析で登場するキーワードをざっくりと定義します。
もちろん上記のVBAオブジェクトライブラリ定義以外となります。
悪戦苦闘で以下のように定義しました。(最終的には完結予定)
VBAで登場する予約語をまとめました。
たぶん抜けや誤字・脱字がありそうです。調整しながら進んでいきます。
構文解析ロジックを組み立てる上で元になるExcelとVBAのサンプルを用意します。
これを最初にJavaScriptへ翻訳して構文解析ロジックの正規化を図りたいと思います。
問題のテキスト(wikiなどからコピペ)。
穴埋め問題にしたいテキストを赤文字に変更します。
(A,6)セルに=AnzColor(A1,3)を入力します。
※カラーインデックス=3は赤
(A,8)セルに=AnsColor(A1,3)を入力します。
※カラーインデックス=3は赤
ばたばたと予約語と翻訳対象のVBAを作成しました。
途中で路線変更しそうな予感です。
このあたりが一番退屈なところかもしれません。
予約語はこんな感じぐらいで認識しましょう。
はじめに
前回は、VBAを字句解析する簡単なサンプルプログラムを作成しました。今回は、VBAの構文解析する前提としてVBAの予約語を定義したいと思います。
あわせてVBA翻訳のサンプルVBAを提示します。
前提
- OS : Windows7以上
- PoweShellのターミナルで実行
- VSCodeでコード編集
- node.js環境構築済み
VBEのオブジェクトブラウザーからVBAの予約語を取り出す
VBEとはVBAを編集するためのExcelに同梱されたエディターです。ExcelからAtl+F11で起動できます。
VBAのライブラリの定義をここから参照して予約語をまとめます。
赤丸のボタンをマウスでクリックします。
すべてのライブラリと表示のあるドロップボックスのリストからVBAを選択します。
クラスのリストボックスのCollectionを選択します。Collectionのメンバーのリストが表示されます。
この内容を以下のように定義してみます。
var vba_Module_Collection = [Add, Count, Item, Remove];
以下となります。
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 | セルアドレス、カラーインデックス | 元文の指定したカラー文字を抽出します |
問題集を作る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を作成しました。途中で路線変更しそうな予感です。
このあたりが一番退屈なところかもしれません。
予約語はこんな感じぐらいで認識しましょう。
コメント
コメントを投稿