簡體   English   中英

"如何在 VBA 中將字符串作為命令運行"

[英]How to run a string as a command in VBA

我在下面有這個簡單的 VBA 代碼,我不知道為什么不起作用。

Sub Run()
    test = "MsgBox" & """" & "Job Done!" & """"
    Application.Run test     
End Sub

我想要做的是將 VBA 命令作為文本放入變量中並將其作為命令運行。 在這種情況下,我想像MsgBox "Job Done!"一樣運行。 並打印:

任務完成!

您可能會想添加自己的字符串“執行者”:

Sub StringExecute(s As String)
    Dim vbComp As Object
    Set vbComp = ThisWorkbook.VBProject.VBComponents.Add(1)
    vbComp.CodeModule.AddFromString "Sub foo()" & vbCrLf & s & vbCrLf & "End Sub"
    Application.Run vbComp.name & ".foo"
    ThisWorkbook.VBProject.VBComponents.Remove vbComp
End Sub

Sub Testing()
    StringExecute "MsgBox" & """" & "Job Done!" & """"
End Sub

簡短的回答是,您不能那樣做(您不應該那樣做)但是……閱讀以下內容以找出原因並查看解決方法!

如您所知,您正在編譯器中編寫代碼。 您想要做的是將人類可讀的文本行作為不可能的命令運行。 當您運行程序時,所有程序都被編譯為機器語言。 當您將那行文本傳遞給它時,它無法將其識別為命令,您最終會收到錯誤消息。 你可以做的是向它傳遞參數:

Sub Run()
 test = "Job Done" 
 MsgBox(test)
End Sub

您還可以運行可執行文件,該可執行文件可以在macro編寫為文本文件,然后在同一個Sub運行(需要注意擴展)。

如果您無法更改變量(即test ),那么您需要對它采取另一種方法。 我建議像提取可以傳遞給函數的參數並使用它。 像下面這樣;

Sub Run()

 test = "MsgBox" & """" & "Job Done!" & """"

 extest = Right(test, Len(test) - 7)

 MsgBox (extest)

End Sub

我相信 SO 上也有同樣的問題,但我找不到。 如果找到它,我會將其包含為參考。

PS這兩個帖子可能有助於找到答案:

訪問 VBA - 使用字符串參數評估函數

Excel VBA - 如何將字符串作為一行代碼運行

另一種解決方案

這需要信任VB項目。 ExcelForum引用並引用對Visual Basic 項目的編程訪問不受信任 - Excel

引用:

將您的啟用宏的工作簿放在您可以指定為宏友好的文件夾中。

然后打開工作簿。

Click on the Office Button -> Excel Options -> Trust Center -> Trust Center Setting -> Trusted Locations.

然后將您的文件夾(您的 Excel 啟用宏工作簿所在的位置)添加為受信任位置。

你還需要這樣做:

File -> Options -> Trust Center -> Trust Center Setting -> Macro Setting -> Check the box beside "Trust access to the VBA project object model"

關閉並重新打開您的工作簿。

那些使用你的宏的人應該經歷同樣的步驟。

取消報價。

然后你可以使用我從VBA得到的這個- 在 Excel 中執行字符串作為命令(這未經測試)

Sub test()
 Set VBComp = ThisWorkbook.VBProject.VBComponents.Add(vbext_ct_StdModule)
 VBComp.Name = "NewModule"
 Set VBCodeMod = ThisWorkbook.VBProject.VBComponents("NewModule").CodeModule

 Dim test As String
 test = "MsgBox " & """" & "Job Done!" & """"

 With VBCodeMod
    LineNum = .CountOfLines + 1
    .InsertLines LineNum, _
    "Sub MyNewProcedure()" & Chr(13) & test & Chr(13) & "End Sub"
 End With
 'run the new module
 Application.Run "MyNewProcedure"
 UserForm1.Show
 'Delete the created module
 ThisWorkbook.VBProject.VBComponents.Remove VBComp
End Sub

@ASH 回答做了最后一個解決方案打算實現的事情。 為了完整起見,我將它包括在這里。 您可以參考原始答案並對其進行投票。

Public Sub StringExecute(s As String)
    Dim vbComp As Object
    Set vbComp = ThisWorkbook.VBProject.VBComponents.Add(1)
    vbComp.CodeModule.AddFromString "Sub foo" & vbCrLf & s & vbCrLf & "End Sub"
    Application.Run vbComp.name & ".foo"
    ThisWorkbook.VBProject.VBComponents.Remove vbComp
End Sub

Sub Testing()
    StringExecute "MsgBox" & """" & "Job Done!" & """"
End Sub

如果您需要一個不需要特殊權限並且比硬編碼代碼更強大的解決方案,我會使用stdLambdastdVBA

Public Sub Main()
   stdLambda.bindGlobal("msgbox", stdCallback.CreateFromModule("mainModule","msgbox"))
   stdLambda.Create("msgbox(""hello world"")").Run()
End Sub
Public Function msgbox(ByVal sMessage as string) as long
   msgbox = VBA.msgbox(sMessage)
End Function

stdLambda語法類似於 vba,但它本身就是一種完全嵌入式的編程語言。 有關更多詳細信息,請參閱文檔

我遇到了類似的變體:宏名稱在“控制規范”工作表中。 在功能區 XML 中添加了帶有“onAction”參數的自定義功能區。 “標記”名稱在功能區回調宏中返回,然后用於查找要根據 XML 標記名稱運行的宏名稱。 到目前為止有道理!!!! 我已經在現有的代碼模塊 = [m0_RibbonCallBack] 中有處理潛艇。 在 [m0_RibbonCallBack] 模塊中,當我單擊帶有 tagName=[Reset2CellA2] 的功能區按鈕時,我想運行 sub name=[mResetToCellA2]。 在“控制規范”工作表中,我對 tagname=[Reset2CellA2] 執行了 vLookUp(),並從第 3 列 (onAction) =“mResetToCellA2”返回了字符串值。 現在我需要在 VBA 端運行宏字符串(macroName)名稱!!! 最后我用這個簡單的語句解決了這個挑戰:Application.Run“m0_RibbonCallBack”。 &宏名
干杯!

"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM