在Excel中构建不需要最终用户安装的工具

时间:2014-10-16 12:24:22

标签: vba vsto

是否可以在Microsoft Excel中构建不需要最终用户安装的工具/加载项。

例如,我们使用VBA构建基于excel的工具,但语言非常基础。还有其他类似于VBA或VSTO的技术吗?

谢谢, Jayanth

1 个答案:

答案 0 :(得分:0)

  1. 没有。 (虽然管理员可以为用户执行此操作)但是所有用户必须做的是双击某些内容(excel表,word文档,批处理文件,vbsfile,jscript,exe(在{strong>开始 - 运行<中键入iexpress) /强>)。

  2. 它被称为Visual Basic,所以它是Basic。但是这种语言编写起来很简单,并且在功能方面不是基本的。它可以做任何其他语言可以做的事情。使用COM,它可以在10行中完成C程序员数百个。任何其他语言都可以这样做,VB / VBA,通常只有很少的行。

  3. 也许你应该考虑一下你的问题。

    1号是那些想要编写病毒的人的最爱,这就是为什么在没有他人许可的情况下安装代码是不可能的。视情况而定,可能违法。

    2号,我怀疑你真的不知道如何使用VBA。请记住,有VBA和Excel,它们是分开的。如果你一直在编程Excel,你可能还没有学到很多VBA,更有可能你学习了Excel的对象模型。

    请记住,VB6和VBA是相同的语言(并且vbscript可以粘贴到VB6 / VBA中)以不同方式托管。如果寻找解决方案,请查看VB6 / VBA / VBScript。在VBA / VB6 / VBScript中编写基本电子表格非常简单。

    VB6 / VBA是简单的COM程序,它们可以使用数千个对象。可以调用API调用,因此可以执行任何操作。

    这是一个随机化文本文件中的行的程序。它是VBScript和adodb(主要的Windows数据库对象)。它在内存中创建一个数据库,添加一个随机数和文本行,对其进行排序,将数据库写出来。

    Sub Randomise
        Randomize 
        Set rs = CreateObject("ADODB.Recordset")
        With rs
            .Fields.Append "RandomNumber", 4 
    
            .Fields.Append "Txt", 201, 5000 
            .Open
            Do Until Inp.AtEndOfStream
                .AddNew
                .Fields("RandomNumber").value = Rnd() * 10000
                .Fields("Txt").value = Inp.readline
                .UpDate
            Loop
            .Sort = "RandomNumber"
            Do While not .EOF
                Outp.writeline .Fields("Txt").Value
                .MoveNext
            Loop
        End With
    End Sub
    

    或者说一行文字的脚本。

    Sub Speak
            Set objVoice = CreateObject("SAPI.SpVoice")
            Do Until Inp.AtEndOfStream
                Line=Inp.readline
                outp.writeline Line
                objVoice.Speak Line
            Loop
    End Sub
    

    或者您可能希望为项目添加宏语言。这将在命令行上针对文件的每一行运行一个vbs脚本。这包括语法检查等,

    Sub VBSCmd
        RawScript = Arg(1)
        'Remove ^ from quoting command line and replace : with vbcrlf so get line number if error
        Script = Replace(RawScript, "^", "")
        Script = Replace(Script, "'", chr(34))
        Script = Replace(Script, ":", vbcrlf)
        'Building the script with predefined statements and the user's code
        Script = "Dim gU" & vbcrlf & "Dim gdU" & vbcrlf & "Set gdU = CreateObject(" & chr(34) & "Scripting.Dictionary" & chr(34) & ")" & vbcrlf & "Function UF(L, LC)" & vbcrlf & "Set greU = New RegExp" & vbcrlf & "On Error Resume Next" & vbcrlf & Script & vbcrlf & "End Function" & vbcrlf
    
        'Testing the script for syntax errors
        On Error Resume Next
        set ScriptControl1 = wscript.createObject("MSScriptControl.ScriptControl",SC)
            With ScriptControl1
                .Language = "VBScript"
                .UseSafeSubset = False
                .AllowUI = True
            .AddCode Script
        End With
        With ScriptControl1.Error
            If .number <> 0 then
                Outp.WriteBlankLines(1)
                Outp.WriteLine "User function syntax error"
                Outp.WriteLine "=========================="
                Outp.WriteBlankLines(1)
                Outp.Write NumberScript(Script)
                Outp.WriteBlankLines(2)
                Outp.WriteLine "Error " & .number & " " & .description
                Outp.WriteLine "Line " & .line & " " & "Col " & .column
                Exit Sub
            End If
        End With
    
        ExecuteGlobal(Script)
    
        'Remove the first line as the parameters are the first line
        'Line=Inp.readline  
        Do Until Inp.AtEndOfStream
            Line=Inp.readline
            LineCount = Inp.Line        
            temp = UF(Line, LineCount)
            If err.number <> 0 then 
                outp.writeline ""
                outp.writeline ""
                outp.writeline "User function runtime error"
                outp.writeline "==========================="
                Outp.WriteBlankLines(1)
                Outp.Write NumberScript(Script)
                Outp.WriteBlankLines(2)
                Outp.WriteLine "Error " & err.number & " " & err.description
                Outp.WriteLine "Source " & err.source
    
                Outp.WriteLine "Line number and column not available for runtime errors"
                wscript.quit
            End If
            outp.writeline temp
        Loop
    End Sub
    

    从对象到API调用的速度变化。

    这会创建一个在VB6之后发布的Richtext控件,因此不会内置。

    Ret = LoadLibrary("c:\windows\system32\MSFTEDIT.dll")
        If Ret = 0 Then MsgBox "Load Lib " & Err.LastDllError
        Flags = WS_CHILD + WS_HSCROLL + WS_VSCROLL + WS_VISIBLE + ES_MULTILINE + ES_AUTOHSCROLL + ES_AUTOVSCROLL + ES_NOHIDESEL + ES_WANTRETURN
        Dim barray() As Byte
        barray = "RICHEDIT50W" & vbNullChar
        gRtfHwnd = CreateWindowEx(WS_EX_ACCEPTFILES + WS_EX_CLIENTEDGE, barray(0), "", Flags, 0, 0, ScaleX(Me.ScaleWidth, vbTwips, vbPixels), ScaleY(Me.ScaleHeight, vbTwips, vbPixels), Me.hWnd, vbNull, App.hInstance, vbNull)
    
        Ret = SendMessageByVal(gRtfHwnd, EM_SETTEXTMODE, TM_MULTILEVELUNDO + TM_PLAINTEXT + TM_MULTICODEPAGE, 0)
        If GetTextMode(gRtfHwnd) <> 41 Then MsgBox "get Text mode = " & GetTextMode(gRtfHwnd)
        Ret = SendMessageByVal(gRtfHwnd, EM_SETEDITSTYLE, SES_ALLOWBEEPS + SES_USECRLF, SES_ALLOWBEEPS + SES_USECRLF)
        Ret = SendMessageByVal(gRtfHwnd, EM_SETLANGOPTIONS, IMF_None, IMF_None)
        If GetTextMode(gRtfHwnd) <> 41 Then MsgBox "get Text mode (2) = " & GetTextMode(gRtfHwnd)
        Ret = SendMessageByVal(gRtfHwnd, EM_SETTYPOGRAPHYOPTIONS, TO_None, TO_None)
        'Below is the default anyway with CreateWin flags spec above
        Ret = SendMessageByVal(gRtfHwnd, EM_SETOPTIONS, ECO_AUTOHSCROLL + ECO_AUTOVSCROLL + ECO_NOHIDESEL + ECO_WANTRETURN, ECOOP_OR)
    
    
        SetFocusAPI gRtfHwnd
        Me.Show
    
    Dim ParaFormat As ITextPara
    Dim FontFormat As ITextFont
    Ret = SendMessageAny(gRtfHwnd, EM_GETOLEINTERFACE, 0, TomObj)