1. 程式人生 > >向Excel文件中嵌入VBA控制元件和UserForm並顯示

向Excel文件中嵌入VBA控制元件和UserForm並顯示

實現環境:Visual Studio 2010, Excel 2010, VSTO 4.0

在文件中嵌入一個Commandbutton點選它會顯示一個UserForm,UserForm上有一個CommandButton點選會彈出訊息框然後CommandButton的Caption改變。當UserForm關閉是文件中的CommandButton的Caption改變。

VB.NET:

Imports Microsoft.Office.Tools.Ribbon
Imports VBE = Microsoft.Vbe.Interop
Imports Forms = Microsoft.Vbe.Interop.Forms

Public Class Ribbon1
    Private WithEvents objCommandButton As Forms.CommandButton

    Private Sub Ribbon1_Load(ByVal sender As System.Object, ByVal e As  _
                             RibbonUIEventArgs) Handles MyBase.Load

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e _
As Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs) Handles Button1.Click
        Dim objApplicatin As Excel.Application = Globals.ThisAddIn.Application
        Dim objWorkbook As Excel.Workbook = objApplicatin.ActiveWorkbook
        Dim objWorksheet As Excel.Worksheet = objWorkbook.ActiveSheet
        Dim objShape As Excel.Shape
        Dim objOLEObject As Excel.OLEObject
        Dim strModuleSnippet As String
        Dim objVBAProject As VBE.VBProject
        Dim objVBComponent As VBE.VBComponent
        Dim objVBFormComponent As VBE.VBComponent
        Dim objObjectFormButton As Object

        objShape = objWorksheet.Shapes.AddOLEObject("Forms.CommandButton.1")
        objShape.Name = "btn1"
        objOLEObject = objWorksheet.OLEObjects("btn1")
        Try
            objCommandButton = TryCast(objOLEObject.Object, Forms.CommandButton)
            objCommandButton.Caption = "Click Me"
            strModuleSnippet = "private sub btn1_Click()" & Chr(13) & _
                "UserForm1.Show " & Chr(13) & "end sub"
            '當前的VBA工程
            objVBAProject = objApplicatin.VBE.VBProjects(0)
            '當前Worksheet的Componet
            objVBComponent = objVBAProject.VBComponents(0)
            '加入程式碼
            objVBComponent.CodeModule.AddFromString(strModuleSnippet)
            '加一個UserForm
            objVBFormComponent = objVBAProject.VBComponents.Add( _
                VBE.vbext_ComponentType.vbext_ct_MSForm)
            '加一個CommandButton
            objObjectFormButton = objVBFormComponent.Designer.Controls.Add( _
                "Forms.CommandButton.1")
            objObjectFormButton.Caption = "Form Button"
            objObjectFormButton.Name = "frmbtn1"
            '由於這個Button在UserForm內所以不能像上一個Button一樣直接寫事件控制
            '這個Button的事件必須用VBA程式碼控制
            strModuleSnippet = "private sub frmbtn1_Click()" & Chr(13) & _
                "Msgbox ""Hello World"" " & Chr(13) & _
                "frmbtn1.Caption = ""This is a Test""" & Chr(13) & "end sub"
            objVBFormComponent.CodeModule.AddFromString(strModuleSnippet)
        Catch ex As Exception
            MsgBox(ex.Message & Chr(13) & ex.StackTrace)
        End Try
    End Sub

    Private Sub objCommandButton_Click() Handles objCommandButton.Click
        objCommandButton.Caption = "Hello World"
    End Sub
End Class

C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Tools.Ribbon;
using VBE = Microsoft.Vbe.Interop;
using Forms = Microsoft.Vbe.Interop.Forms;
using Excel = Microsoft.Office.Interop.Excel;

namespace ExcelAddIn16
{
    public partial class Ribbon1
    {
        private Forms.CommandButton objCommandButton = null;
        private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
        {

        }

        private void button1_Click(object sender, RibbonControlEventArgs e)
        {
            Excel.Application objApplication = Globals.ThisAddIn.Application;
            Excel.Workbook objWorkbook = objApplication.ActiveWorkbook;
            Excel.Worksheet objWorksheet = objWorkbook.ActiveSheet;
            Excel.Shape objShape = objWorksheet.Shapes
                .AddOLEObject("Forms.CommandButton.1");
            objShape.Name = "btn1";
            Excel.OLEObject objOLEObject = objWorksheet.OLEObjects("btn1");
            string strModuleString = string.Empty;
            if (objOLEObject.Object is Forms.CommandButton)
            {
                objCommandButton = 
                    (Forms.CommandButton)objOLEObject.Object;
                objCommandButton.Caption = "Embedded Button";
                objCommandButton.Click += 
                    new Forms.CommandButtonEvents_ClickEventHandler
                        (objCommandButton_Click);
                VBE.VBProject objVBProject = objApplication.VBE.ActiveVBProject;
                VBE.VBComponent objVBComponet = objVBProject.VBComponents
                    .Item("Sheet1");
                strModuleString = "Private Sub btn1_Click()\nUserForm1.Show\n"
                    + "End Sub";
                objVBComponet.CodeModule.AddFromString(strModuleString);
                VBE.VBComponent objUserFormComponent = 
                    objVBProject.VBComponents.Add
                    (VBE.vbext_ComponentType.vbext_ct_MSForm);
                var objFormButton = objUserFormComponent.Designer.Controls.
                    Add("Forms.CommandButton.1");
                objFormButton.Caption = "Try to Click Me";
                objFormButton.Name = "frmbtn1";
                strModuleString = "Private Sub frmbtn1_Click()\nMsgbox \"Hello "
                    +"World!\"\nfrmbtn1.Caption=\"This is a test!\"\nEnd Sub";
                objUserFormComponent.CodeModule.AddFromString(strModuleString);
            }
        }

        void objCommandButton_Click()
        {
            objCommandButton.Caption = "Hellow World";
        }
    }
}