VSTO外接程序與VBA的聯動嘗試

文章目錄

  • 前言
  • 一、第一坑:安裝offic2007后excel加載項找不到了
  • 二、示例1 通過Ribbon XML自定義Excel主菜單并添加新項
  • 二、示例1 總結
  • 三、示例2 創建VSTO外接程序
  • 三、示例2 總結
  • 四、示例 3 C# VSTO外接程序示例
  • 四、示例 3 總結
  • 五、實現C# 的VSTO調用VBA函數(xlam)
  • 六、結語

前言

這幾天玩VBA,
嘗試XML繪制EXCEL主菜單,注入EXCEL,并調用VBA的函數。
眾所周知VS的IDE是多強大,我就尋思能不能用C#畫界面去控制VBA的插件。這樣更新就能單xlam覆蓋更新了。
然后開始學習VS的 VSTO外接程序,確實很有意思。

一、第一坑:安裝offic2007后excel加載項找不到了

在這里插入圖片描述
在這里插入圖片描述在這里插入圖片描述
至于為什么使用2007,我尋思07上能跑的13、16不得兼任啊。我用13的開發,還得倒回來弄07、10的兼容不是。

二、示例1 通過Ribbon XML自定義Excel主菜單并添加新項

步驟1:創建Ribbon XML定義文件
新建一個XML文件(如customUI.xml),定義以下結構

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui"><ribbon><tabs><tab id="CustomTab" label="我的工具"><group id="CustomGroup" label="數據處理"><button id="btnCleanData" label="數據清洗" size="large" onAction="DataCleaningMacro"imageMso="DataRefreshAll" /><menu id="mnuAdvanced" label="高級操作" imageMso="GroupEdit"><button id="btnMerge" label="合并工作表" onAction="MergeSheetsMacro"/><button id="btnSplit" label="拆分數據" onAction="SplitDataMacro"/></menu></group></tab></tabs></ribbon>
</customUI>

關鍵參數說明:
imageMso:使用Office內置圖標(如DataRefreshAll代表刷新圖標)3
onAction:綁定VBA回調函數

步驟2:將XML集成到Excel文件
將Excel文件后綴改為.zip
在壓縮包內創建路徑:customUI/_rels
將customUI.xml放入customUI文件夾
創建關系文件customUI/_rels/customUI.xml.rels:

<?xml version="1.0" encoding="UTF-8"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="/customUI/customUI.xml" Id="RibbonCustomization" />
</Relationships>

步驟3:編寫VBA回調函數
在Excel的VBA編輯器中添加模塊(需啟用宏):

' 按鈕點擊事件處理
Sub DataCleaningMacro(control As IRibbonControl)MsgBox "執行數據清洗操作", vbInformation' 實際功能代碼
End SubSub MergeSheetsMacro(control As IRibbonControl)MsgBox "執行工作表合并", vbInformation
End Sub

步驟4:驗證與調試
通過Custom UI Editor工具直接注入XML(推薦)
使用IRibbonUI.Invalidate方法刷新界面:

Dim MyRibbon As IRibbonUISub ribbonLoaded(ribbon As IRibbonUI)Set MyRibbon = ribbon
End SubSub RefreshRibbon()MyRibbon.Invalidate
End Sub

二、示例1 總結

這個示例過于復雜,而且卡在第四步,我覺得應該尋找更好、更簡單的辦法。

三、示例2 創建VSTO外接程序

步驟1:新建解決方案和Excel VSTO 外接程序項目

創建一個Excel VSTO外接程序的新項目,選擇“Excel VSTO外接程序(Visual Basic)”模板,命名為“外接程序安裝”。VS將顯示解決方案名稱為“外接程序安裝”,包含“外接程序安裝”項目。

步驟2:設計Excel VSTO外接程序

主要是設計菜單項和代碼。

1.在“外接程序安裝”項目上,點擊右鍵,選擇“添加”——“類”,在“添加新項-外接程序安裝”界面,選擇“office/sharepoint”中的“功能區(可視化設計器)”,點擊“添加”后默認建立“Ribbon1.vb”的模塊。

2.依次右鍵點擊“Group1”、“TabAddins(內置)”,均選擇“ 刪除”。

(1)點擊左側的“工具箱”,拖拽“Office 功能區控件”中的Tab按鈕到“Ribbon1.vb[設計]”中,修改右側屬性的有關值,如Label改為“關于”等。

(2)再次點擊左側的“工具箱”,拖拽“Office 功能區控件”中的Group按鈕到“Ribbon1.vb[設計]”的“關于”里面,修改右側屬性的有關值,如Label改為“幫助”等。

(3)點擊左側的“工具箱”,拖拽“Office 功能區控件”中的Group按鈕到“Ribbon1.vb[設計]”中的幫助里面,修改右側屬性的有關值,如Label改為“版本”,ControlSize改為“RibbonControlSizeLarge”,OfficeImageId改為“Help”等。

3.雙擊“版本”圖標,進入“Ribbon1.vb”的代碼編輯界面,在Button1_Click的過程中,輸入以下代碼

MsgBox(“version 1.0.0.0”)

引用資料: 創建 VSTO 外接程序的windows安裝包
https://blog.csdn.net/weixin_45661908/article/details/123310069

三、示例2 總結

跟著做了一遍,在第二條:MsgBox(“version 1.0.0.0”) 這里卡住了。
思路了半天,反應過來,他是用的VB,而我用的C#。 尷尬了
在這里插入圖片描述
嗯 最終跟著做完,挺詳細、簡單的,安裝那部分不用過分深入,了解就行。主要是熟悉外接程序的搭建。

四、示例 3 C# VSTO外接程序示例

步驟1:創建一個Excel外接程序:
在這里插入圖片描述

步驟2:添加項,添加一個Ribbon菜單:
在這里插入圖片描述

步驟3 : 熟悉Tab控件

在這里插入圖片描述
在這里插入圖片描述
RibbonTab控件是所有控件的容器

步驟4: 熟悉Group控件

Group控件的作用是將我們的功能進行分組。回到我們之前的規劃,我們的歪歪插件有財經,地圖,天氣,關于這幾大功能。所以我們需要在界面上放置4個Group控件,并對其進行命名。

在這里插入圖片描述

步驟5 :Menu控件和SpliterButton控件

在分好類之后,我們需要對每個分類的細小功能進行設計,這里面我們需要放置各種控件,首先我們可能會接觸到的就是Menu控件,里面可以包含Button,SplitButton等。
在這里插入圖片描述

步驟6:RibbonXml
在Office中Ribbon菜單時可以通過RibbonXML進行配置,也就是說,上面的可視化界面設計其實是為我們提供了編輯RibbonXML的設計時支持。其實我們也可以直接創建一個XML文件進行設計,然后在代碼中進行加載,同樣能夠實現這樣的功能。在有些情況下,比如我們創建SharedAddin程序時,根本沒有設計時支持。所以了解RibbonXML對于創建可兼容多版本Excel菜單系統顯得尤為重要。

要創建RibbonXML最好的做法是對著新建的可視化菜單,然后右鍵->將功能區導出到XML。然后項目會自動創建Ribbon.xml和Ribbon.cs文件,其中Ribbon.xml是布局文件,Ribbon.cs是事件處理代碼。
在這里插入圖片描述

打開Ribbon.xml可以看到如下代碼,可以看到這個UI界面的展現即是使用了該XML文件來進行渲染的,其中在XML中還可以聲明一些事件,后面會講。
在這里插入圖片描述

現在,如何在我們的應用程序中加載該RibbonXML并渲染出Ribbon菜單呢?首先,我們將之前的添加的可視化設計的Ribbon菜單YYMenu.cs排除到項目外。然后轉到ThisAddIn.cs中,覆寫Office.IRibbonExtensibility 接口的CreateRibbonExtensibilityObject方法,實例化自動生成的Ribbon類,然后返回。

//ThisAddIn.cs
private Ribbon customerRibbon;protected override Office.IRibbonExtensibility CreateRibbonExtensibilityObject()
{customerRibbon = new Ribbon();return customerRibbon;
}

運行程序,即可看到如下效果:

在這里插入圖片描述

可以看到圖片不見了,這是因為在導出功能區為XML的時候,VS沒有幫我們處理圖片,所以需要我們自己來添加。在RibbonXML文檔中, customUI節點下有loadImage事件,Button有getImage事件和image屬性。customUI節點的loadImage方法和子節點的image屬性一起使用,image屬性作為loadImage方法的參數。

在這里插入圖片描述
loadImage方法如下:

//Ribbon.cs
public Image LoadImage(string imageName)
{Assembly assembly = Assembly.GetExecutingAssembly();//String[] all =assembly.GetManifestResourceNames();//GetResourceNameStream stream = assembly.GetManifestResourceStream("YYAddIn.Resources." + imageName);return Image.FromStream(stream);
}

其中,imageName即為Button控件的image屬性要設置的圖片名稱。資源文件圖片,要設置為嵌入的資源。

引用資料: 淺談Excel開發:二 Excel 菜單系統
https://blog.csdn.net/dyllove98/article/details/9707613

四、示例 3 總結

示例3是最符合我需求的測試,它為我初衷‘便捷的調用VBA 創造了可能’。當然也遇到一些問題。

問題1:老是被EXCEL 的加載項禁用,需要手動解除。不然就尷尬了
在這里插入圖片描述
在這里插入圖片描述
問題2:步驟6,圖片出不來,忘記設置本地資源屬性設置造成的。

在這里插入圖片描述
在這里插入圖片描述

五、實現C# 的VSTO調用VBA函數(xlam)

C#調用VBA(xlam)的代碼我會放文末。不管作用大小,好歹是個思路。主要代碼如下。

步驟1:添加一個測試項目 test2,做界面就是group里加個button,然后生成XML

步驟2:我的測試界面生成的XML
在這里插入圖片描述

<?xml version="1.0" encoding="UTF-8"?>
<customUI onLoad="Ribbon_Load" xmlns="http://schemas.microsoft.com/office/2006/01/customui"  loadImage="LoadImage"><ribbon><tabs><tab id="tab1" label="mytest2"><group id="group1" label="group1"><button id="button1" label="button1" size="large"   image="exlLogo.jpg"  onAction="testdo1" /></group></tab></tabs></ribbon>
</customUI>

XML 中加入LoadImage、testdo1 ,LoadImage加載圖片、testdo1是我想調用的xlam函數。

步驟3: 項目中排除界面文件Ribbon1.cs,
ThisAddIn.cs 中添加 啟用XML生成

private Ribbon customerRibbon;protected override Office.IRibbonExtensibility CreateRibbonExtensibilityObject()
{customerRibbon = new Ribbon();return customerRibbon;
}

步驟4:Ribbon.cs寫入 本地圖片加載

public Image LoadImage(string imageName) {Assembly assembly = Assembly.GetExecutingAssembly();//String[] all = assembly.GetManifestResourceNames();//GetResourceName//return null;Stream stream = assembly.GetManifestResourceStream("test2.Resources." + imageName);return Image.FromStream(stream);}

步驟5:建一個測試VBA 函數 并保存為 ‘我的測試.xlam’
在這里插入圖片描述
在這里插入圖片描述
不需要添加到excel加載項,因為這樣外接程序也讀取不到,我測試過了。

步驟6:修改按鈕事件響應

將Ribbon.cs 的 GetCustomUI 用下面代碼覆蓋掉

 Microsoft.Office.Interop.Excel.Application excelApp = null;public string GetCustomUI(string ribbonID){excelApp = Globals.ThisAddIn.Application;// 加載xlam文件(若未自動加載)excelApp.Workbooks.Open(@"C:\Users\cs\Desktop\我的測試.xlam", ReadOnly: true);return GetResourceText("test2.Ribbon.xml");}public void testdo1(Office.IRibbonControl control){excelApp.Run("我的測試.xlam!模塊1.testdo1");/*// 方式2:傳遞參數調用object arg1 = "參數1";object arg2 = 100;excelApp.Run("MyMacro.xlam!Module1.ProcessData", arg1, arg2);// 方式3:使用動態類型(需引用Microsoft.CSharp)dynamic excel = excelApp;excel.Run("MyMacro.xlam!Module1.AdvancedCalc", 15.5, DateTime.Now);*//* try{if (control.Id.Equals("btntest")){}}catch (COMException ex){Console.WriteLine("Create CTP encounter errors: " + ex.ToString());}*/}

運行效果:
在這里插入圖片描述

六、結語

1、最終,貼一下本文的測試代碼下載
C# 的VSTO調用VBA函數(xlam)示例代碼
https://download.csdn.net/download/yqsy123123/90724022

我也不知道直接更新覆蓋VBA的文件夾、和寫一個自動更新的程序哪個更復雜,主要是想到了看能不能實現,還是挺有意思的

2、至于,寫好的VSTO如何注入EXCEL,那就得參考示例2 的安裝部分了。
創建 VSTO 外接程序的windows安裝包
https://blog.csdn.net/weixin_45661908/article/details/123310069

3、標記一個EXCEL內置圖標的,
兼容Office和WPS中Word圖標庫
https://blog.csdn.net/weixin_45055317/article/details/133832128
你們有可以預覽的圖標庫地址,分享一個,萬分感謝。

再次感謝本文引用資源的作者。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/79864.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/79864.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/79864.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

DeepSeek驅動的金市情緒量化:NLP解析貿易政策文本的情緒傳導路徑

【AI觀察】政策信號與市場情緒的量化關聯 基于自然語言處理技術對全球財經文本的情緒分析顯示&#xff0c;4月30日亞盤時段現貨黃金價格波動率較前日下降12.3%&#xff0c;與技術面修正指標呈現強相關性。特政府最新關稅政策調整引發市場風險偏好指數&#xff08;RPI&#xff…

期末代碼Python

以下是 學生信息管理系統 的簡化版代碼示例&#xff08;控制臺版本&#xff0c;使用文件存儲數據&#xff09;&#xff0c;包含核心功能&#xff1a; 1. 定義學生類 class Student: def __init__(self, sid, name, score): self.sid sid # 學號 self.name name # 姓名 self.s…

zotero pdf中英翻譯插件使用

最近發現一個pdf中英翻譯的神器zotero-pdf2zh&#xff0c;按照官方安裝教程走一遍的時候&#xff0c;發現一些流程不清楚的問題&#xff0c; 此文就是整理一些安裝需要的文件以及遇到的問題&#xff1a; 相關文件下載地址 Zotero 是一款免費的、開源的文獻管理工具&#xff0…

本地MySQL連接hive

1、首先需要修改MySQL的配置&#xff0c;允許遠程連接&#xff1a; # 在本地MySQL服務器上執行 sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf找到 bind-address 行&#xff0c;將其修改為&#xff1a; bind-address 0.0.0.02、在本地MySQL中創建用戶并授權&#xff08;注意…

Nginx核心功能2

一&#xff1a;正向代理 正向代理&#xff08;Forward Proxy)是一種位于客戶端和原始服務器之間的代理服務器&#xff0c;其主要作用是將客戶端的請求轉發給目標服務器&#xff0c;并將響應返回給客戶端Nginx的正向代理充當客戶端的“中間人”&#xff0c;代表用戶訪問外部資源…

高定電視,一場關于生活方式的覺醒

需要有自己的工作室&#xff0c;雇用3個以上專職模特&#xff0c;至少15名全職員工和20名技術工匠?&#xff1b; 每年都要參加巴黎高級時裝周&#xff0c;展示至少50款原創設計&#xff1b; 使用的面料必須高質量、昂貴且不同尋常&#xff0c;設計上注重細節和個性&#x…

用PyTorch搭建卷積神經網絡實現MNIST手寫數字識別

用PyTorch搭建卷積神經網絡實現MNIST手寫數字識別 在深度學習領域&#xff0c;卷積神經網絡&#xff08;Convolutional Neural Network&#xff0c;簡稱CNN&#xff09;是處理圖像數據的強大工具。它通過卷積層、池化層和全連接層等組件&#xff0c;自動提取圖像特征&#xff…

Tensorrt 基礎入門

什么是tensorrt? 其他廠商: Qualcomm, Hailo, google TPU tensorrt的優劣勢 使用tensorrt的pipeline tensorrt使用中存在的問題以及解決方案 tensorrt的應用場景 自動駕駛模型部署需要關注的問題&#xff1a; 邊端硬件資源有限 散熱&#xff08;不能水冷&#xff09; 實時性&…

Qt 顯示QRegExp 和 QtXml 不存在問題

QRegExp 和 QtXml 問題 在Qt6 中 已被棄用&#xff1b; 1&#xff09;QRegExp 已被棄用&#xff0c;改用 QRegularExpression Qt5 → Qt6 重大變更&#xff1a;QRegExp 被移到了 Qt5Compat 模塊&#xff0c;默認不在 Qt6 核心模塊中。 錯誤類型解決方法QRegExp 找不到改用 Q…

玩玩OCR

一、Tesseract: 1.下載windows版&#xff1a; tesseract 2. 安裝并記下路徑&#xff0c;等會要填 3.保存.py文件 import pytesseract from PIL import Image def ocr_local_image(image_path):try:pytesseract.pytesseract.tesseract_cmd rD:\Programs\Tesseract-OCR\tesse…

Dify 完全指南(一):從零搭建開源大模型應用平臺(Ollama/VLLM本地模型接入實戰)》

文章目錄 1. 相關資源2. 核心特性3. 安裝與使用&#xff08;Docker Compose 部署&#xff09;3.1 部署Dify3.2 更新Dify3.3 重啟Dify3.4 訪問Dify 4. 接入本地模型4.1 接入 Ollama 本地模型4.1.1 步驟4.1.2 常見問題 4.2 接入 Vllm 本地模型 5. 進階應用場景6. 總結 1. 相關資源…

C++ Windows 打包exe運行方案(cmake)

文章目錄 背景動態庫梳理打包方案一、使用 Vcpkg 安裝靜態庫&#xff08;關鍵基礎配置&#xff09;1. 初始化 Vcpkg2. 安裝靜態庫&#xff08;注意 x64-windows-static 后綴&#xff09; 二、CMakeLists.txt 關鍵配置三、編譯四、驗證 不同平臺代碼兼容\_\_attribute\_\_((pack…

Java學習手冊:Hibernate/JPA 使用指南

一、Hibernate 和 JPA 的核心概念 實體&#xff08;Entity&#xff09; &#xff1a;實體是 JPA 中用于表示數據庫表的 Java 對象。通過在實體類上添加 Entity 注解&#xff0c;JPA 可以將實體類映射到數據庫表。例如&#xff0c;定義一個 User 實體類&#xff1a; import ja…

字符串匹配 之 拓展 KMP算法(Z算法)

文章目錄 習題2223.構造字符串的總得分和3031.將單詞恢復初始狀態所需的最短時間 II 靈神代碼模版 區別與KMP算法 KMP算法可用于求解在線性時間復雜度0(n)內求解模式串p在主串s中匹配的未知當然&#xff0c;由于在KMP算法中&#xff0c;預處理求解出了next數組&#xff0c;也就…

安全為上,在系統威脅建模中使用量化分析

*注&#xff1a;Open FAIR? 知識體系是一種開放和獨立的信息風險分析方法。它為理解、分析和度量信息風險提供了分類和方法。Open FAIR作為領先的風險分析方法論&#xff0c;已得到越來越多的大型組織認可。 在數字化風險與日俱增的今天&#xff0c;企業安全決策正面臨雙重挑戰…

游戲引擎學習第259天:OpenGL和軟件渲染器清理

回顧并為今天的內容做好鋪墊 今天&#xff0c;我們將對游戲的分析器進行升級。在之前的修復中&#xff0c;我們解決了分析器的一些敏感問題&#xff0c;例如它無法跨代碼重新加載進行分析&#xff0c;以及一些復雜的小問題。現在&#xff0c;我們的分析器看起來已經很穩定了。…

訊睿CMS模版常用標簽參數匯總

一、模板調用標簽 1、首頁 網站名稱&#xff1a;{SITE_NAME} 標題&#xff1a;{$meta_title}&#xff08;列表頁通用&#xff09; Keywords&#xff1a;{$meta_keywords} Description&#xff1a;{$meta_description}2、列表頁 迅睿cms調用本欄目基礎信息標簽代碼 當前欄目…

【C#】Buffer.BlockCopy的使用

Buffer.BlockCopy 是 C# 中的一個方法&#xff0c;用于在數組之間高效地復制字節塊。它主要用于操作字節數組&#xff08;byte[]&#xff09;&#xff0c;但也可以用于其他類型的數組&#xff0c;因為它直接基于內存操作。 以下是關于 Buffer.BlockCopy 的詳細說明和使用示例&…

記一次pdf轉Word的技術經歷

一、發現問題 前幾天在打開一個pdf文件時&#xff0c;遇到了一些問題&#xff0c;在Win10下使用WPS PDF、萬興PDF、Adobe Acrobat、Chrome瀏覽器打開都是正常顯示的&#xff1b;但是在macOS 10.13中使用系統自帶的預覽程序和Chrome瀏覽器&#xff08;由于macOS版本比較老了&am…

在Laravel 12中實現4A日志審計

以下是在Laravel 12中實現4A&#xff08;認證、授權、賬戶管理、審計&#xff09;日志審計并將日志存儲到MongoDB的完整方案&#xff08;包含性能優化和安全增強措施&#xff09;&#xff1a; 一、環境配置 安裝MongoDB擴展包 composer require jenssegers/mongodb配置.env …