LoginSignup
4
1

More than 5 years have passed since last update.

Excel VBAをJavaScriptに翻訳 その5

Last updated at Posted at 2019-01-08

はじめに

前回は、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などからコピペ)。
穴埋め問題にしたいテキストを赤文字に変更します。

②問題

セルA5に=AnzColor(A1,3)を入力します。
※カラーインデックス=3は赤

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

③解答

セルA8に=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を作成しました。
途中で路線変更しそうな予感です。
このあたりが一番退屈なところかもしれません。
予約語はこんな感じぐらいで認識しましょう。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1