{"id":41,"date":"2016-10-06T20:14:37","date_gmt":"2016-10-06T20:14:37","guid":{"rendered":"http:\/\/www.maxwellmckinnon.com\/blog\/?p=41"},"modified":"2022-03-05T20:34:33","modified_gmt":"2022-03-05T20:34:33","slug":"how-to-call-a-c-net-class-library-from-excel-vba-guided-example","status":"publish","type":"post","link":"http:\/\/maxwellmckinnon.com\/blog\/2016\/10\/06\/how-to-call-a-c-net-class-library-from-excel-vba-guided-example\/","title":{"rendered":"How to call a C# .NET class library from Excel VBA: Guided Example"},"content":{"rendered":"<p>I have made a GUI in C#. Now I want to create an API to use in vba to ease automation and make use of the team&#8217;s existing vba code. This guide gives a basic example of how to do that. Examples I found online were overly complicated and\/or not so useful. This short guide should get you started in calling your C# .NET functions from Excel VBA. If you plan on using a GUI, see the other guide as this approach will run into problems. Please let me know if you have trouble.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Update:<\/strong> As it turns out, <strong>this does not effortlessly lead into a COM accessible GUI as I originally suspected.\u00a0<\/strong>This documentation below works great until you try to add in the actual GUI application. For the GUI application, see this guide:\u00a0<a href=\"http:\/\/www.maxwellmckinnon.com\/blog\/2016\/10\/12\/how-to-tie-a-c-net-gui-to-a-callable-c-net-class-library-dll-from-excel-vba-guided-minimum-framework-example\/\">How to tie a C# .NET GUI to a callable C# .NET class library dll from Excel VBA: Guided Minimum Framework Example<\/a><\/p>\n<p>After making different &#8220;HelloWorldGUI via VBA\/C#&#8221; style minimal working solution examples, I picked Named Pipes for now because it was the easiest solution I found (outside of COM exposed DLL solution below for non-gui applications. .NET 3.5+ required<\/p>\n<p>Possible solutions included:<\/p>\n<ul>\n<li>Run the GUI from the VBA &#8211; No, I want a standalone GUI that can be attached to<\/li>\n<li>Use AutoItX3.dll to literally click the buttons and type using virtual keyboard and mouse &#8211; No, doable but overly difficult and complicated<\/li>\n<li>Use .NET&#8217;s UI automation to control UI elements found through Windows SDK inspect tool &#8211; Pretty good, but since we have the GUI source code, there should be a more direct solution\\<\/li>\n<li>Use UDP port on local machine to link programs<\/li>\n<li>Communicate through set memory location on computer &#8211; too low level. Something should already exist that does this safely without problems<\/li>\n<li>Use WCF (Windows Communication Foundation) Named Pipes to communicate between VBA\/C# and WPF (Windows Presentation Foundation) &#8211; <strong>Looks the cleanest and easiest way<\/strong><\/li>\n<\/ul>\n<h1 id=\"HowtocallaC#.NETclasslibraryfromExcelVBA:GuidedExample-Step-By-StepGuidedExample\">Step-By-Step Guided Example<\/h1>\n<div class=\"toc-macro rbtoc1475783713483\">\n<ul class=\"toc-indentation\">\n<li>Step-By-Step Guided Example<\/li>\n<li>1. Create C# Library Class<\/li>\n<li>2. Make Library Class Visible as COM Library<\/li>\n<li>3. Call Public Functions from Excel VBA<\/li>\n<li>4. Deployment\n<ul class=\"toc-indentation\">\n<li>Unblock the DLL (Windows Security)<\/li>\n<li>Registering the Assembly<\/li>\n<li>\u00a0Related articles<\/li>\n<\/ul>\n<\/li>\n<li>References<\/li>\n<\/ul>\n<h1 id=\"HowtocallaC#.NETclasslibraryfromExcelVBA:GuidedExample-1.CreateC#LibraryClass\">1. Create C# Library Class<\/h1>\n<p>Put this code in a new C# file in a new Visual Studio project. It is bare bones with one simple function that will later be called from Excel vba.<\/p>\n<p>I named the project and solution both ZZTEST_EXCEL_LIB for easy finding in the excel references list.<\/p>\n<div class=\"code panel pdl\">\n<div class=\"codeHeader panelHeader pdl hide-border-bottom\"><b class=\" code-title\">Sample Code<\/b><span class=\"collapse-source expand-control\"><span class=\"expand-control-icon icon expanded\">\u00a0<\/span><span class=\"expand-control-text\">Collapse source<\/span><\/span><\/div>\n<div class=\"codeContent panelContent pdl hide-toolbar show-border-top\">\n<div>\n<div id=\"highlighter_173618\" class=\"syntaxhighlighter c# expanded\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<div class=\"line number7 index6 alt2\">7<\/div>\n<div class=\"line number8 index7 alt1\">8<\/div>\n<div class=\"line number9 index8 alt2\">9<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\" title=\"Hint: double-click to select code\">\n<div class=\"line number1 index0 alt2\"><code class=\"c# keyword\">using<\/code><code class=\"c# plain\">System;<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"c# keyword\">using<\/code><code class=\"c# plain\">System.Collections.Generic;<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"c# keyword\">using<\/code><code class=\"c# plain\">System.Text;<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"c# keyword\">namespace<\/code><code class=\"c# plain\">ZZVISIBLE_FROM_EXCEL_LIBRARY<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"c# plain\">{<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"c# spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"c# keyword\">public<\/code><code class=\"c# keyword\">class<\/code><code class=\"c# plain\">ZZVISIBLE_FROM_EXCEL_CLASS<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"c# spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"c# plain\">{<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"c# spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"c# keyword\">public<\/code><code class=\"c# plain\">Double DotNetMethod_SQR(Double input) <\/code><code class=\"c# comments\">\/\/Return the square of the input<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"c# spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"c# plain\">{<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"c# spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"c# keyword\">return<\/code><code class=\"c# plain\">input * input;<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"c# spaces\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"c# plain\">}<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"c# spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"c# plain\">}<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"c# plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h1 id=\"HowtocallaC#.NETclasslibraryfromExcelVBA:GuidedExample-2.MakeLibraryClassVisibleasCOMLibrary\">2. Make Library Class Visible as COM Library<\/h1>\n<p>In the project properties, change the output type to Class Library<\/p>\n<p>In Assembly Information, check &#8220;make assembly COM-Visible&#8221;<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.maxwellmckinnon.com\/blog\/wp-content\/uploads\/2016\/10\/Untitled_Clipping_100616_011732_PM.jpg\" \/><\/p>\n<p>In the project properties under the build tab, check &#8220;Register for COM interop&#8221;<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.maxwellmckinnon.com\/blog\/wp-content\/uploads\/2016\/10\/Untitled_Clipping_100616_011950_PM.jpg\" \/><\/p>\n<h1 id=\"HowtocallaC#.NETclasslibraryfromExcelVBA:GuidedExample-3.CallPublicFunctionsfromExcelVBA\">3. Call Public Functions from Excel VBA<\/h1>\n<p>In Excel, enable the developer tab and launch visual basic (google this step if unclear)<\/p>\n<p>From visual basic, select tools and then references. Select the desired library, in this case &#8220;ZZTEST_EXCEL_LIB&#8221;<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.maxwellmckinnon.com\/blog\/wp-content\/uploads\/2016\/10\/Untitled_Clipping_100616_012026_PM.jpg\" \/><\/p>\n<div class=\"code panel pdl\">\n<div class=\"codeHeader panelHeader pdl hide-border-bottom\"><span class=\"collapse-source expand-control\"><span class=\"expand-control-text\">Run the VBA code<\/span><\/span><\/div>\n<div class=\"codeHeader panelHeader pdl hide-border-bottom\"><span class=\"collapse-source expand-control\"><span class=\"expand-control-text\">Collapse source<\/span><\/span><\/div>\n<div class=\"codeContent panelContent pdl hide-toolbar show-border-top\">\n<div>\n<div id=\"highlighter_56810\" class=\"syntaxhighlighter vb expanded\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\" title=\"Hint: double-click to select code\">\n<div class=\"line number1 index0 alt2\"><code class=\"vb keyword\">Sub<\/code><code class=\"vb plain\">Test()<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"vb spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"vb keyword\">Dim<\/code><code class=\"vb plain\">test1 <\/code><code class=\"vb keyword\">As<\/code><code class=\"vb keyword\">New<\/code><code class=\"vb plain\">ZZVISIBLE_FROM_EXCEL_CLASS<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"vb spaces\">\u00a0\u00a0\u00a0\u00a0<\/code><code class=\"vb plain\">MsgBox test1.DotNetMethod_SQR(5) <\/code><code class=\"vb comments\">'The function made in C# should return the square the input, 5*5 = 25<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"vb keyword\">End<\/code><code class=\"vb keyword\">Sub<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Voila<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.maxwellmckinnon.com\/blog\/wp-content\/uploads\/2016\/10\/Untitled_Clipping_100616_012114_PM.jpg\" \/><\/p>\n<p>&nbsp;<\/p>\n<h1 id=\"HowtocallaC#.NETclasslibraryfromExcelVBA:GuidedExample-4.Deployment\">4. Deployment<\/h1>\n<p><em>This is great, but it will only work on your computer. You must follow these steps to register the DLL on another computer. TK I am looking into building an installer to do this<\/em><\/p>\n<p>Everything in the\u00a0C:\\Program Files (x86)\\Maxim\\GUI_BRIDGE path must be placed in this exact path on the target computer.<\/p>\n<h2 id=\"HowtocallaC#.NETclasslibraryfromExcelVBA:GuidedExample-UnblocktheDLL(WindowsSecurity)\">Unblock the DLL (Windows Security)<\/h2>\n<p><img decoding=\"async\" src=\"http:\/\/www.maxwellmckinnon.com\/blog\/wp-content\/uploads\/2016\/10\/Untitled_Clipping_100616_012140_PM.jpg\" \/><\/p>\n<h2 id=\"HowtocallaC#.NETclasslibraryfromExcelVBA:GuidedExample-RegisteringtheAssembly\">Registering the Assembly<\/h2>\n<p>Start the command prompt as administrator<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.maxwellmckinnon.com\/blog\/wp-content\/uploads\/2016\/10\/Untitled_Clipping_100616_012210_PM.jpg\" \/><\/p>\n<p>In the terminal window, run regasm with \/codebase option on the dll.<\/p>\n<p>&#8220;C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\RegAsm.exe&#8221; \/codebase &#8220;C:\\Program Files (x86)\\Maxim\\GUI_BRIDGE2\\gui_bridge2_project\\gui_bridge2_project\\bin\\Debug\\ZZ_GUI_BRIDGE2_PROJECT.dll&#8221;<\/p>\n<p>Regasm will warn about RA0000 ~ please give your assembly a strong name and re-register it. Types registered successfully.<\/p>\n<\/div>\n<h1 id=\"HowtocallaC#.NETclasslibraryfromExcelVBA:GuidedExample-References\">References<\/h1>\n<p><a class=\"external-link\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb608604.aspx\" rel=\"nofollow\">http:\/\/msdn.microsoft.com\/en-us\/library\/bb608604.aspx<\/a><\/p>\n<p><a class=\"external-link\" href=\"http:\/\/www.codeproject.com\/Articles\/555660\/Extend-your-VBA-code-with-Csharp-VB-NET-or-Cpluspl\" rel=\"nofollow\">http:\/\/www.codeproject.com\/Articles\/555660\/Extend-your-VBA-code-with-Csharp-VB-NET-or-Cpluspl<\/a><\/p>\n<p><a class=\"external-link\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/tzat5yw6(v=vs.110).aspx\" rel=\"nofollow\">http:\/\/msdn.microsoft.com\/en-us\/library\/tzat5yw6(v=vs.110).aspx<\/a><\/p>\n<p><a class=\"external-link\" href=\"http:\/\/www.geeksengine.com\/article\/create-dll.html\" rel=\"nofollow\">http:\/\/www.geeksengine.com\/article\/create-dll.html<\/a><\/p>\n<p><a class=\"external-link\" href=\"http:\/\/richnewman.wordpress.com\/2007\/04\/15\/a-beginner%E2%80%99s-guide-to-calling-a-net-library-from-excel\/\" rel=\"nofollow\">http:\/\/richnewman.wordpress.com\/2007\/04\/15\/a-beginner%E2%80%99s-guide-to-calling-a-net-library-from-excel\/<\/a><\/p>\n<p><a class=\"external-link\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb608613.aspx\" rel=\"nofollow\">http:\/\/msdn.microsoft.com\/en-us\/library\/bb608613.aspx<\/a>\u00a0&#8211; debugging deployment issue<\/p>\n<p><a class=\"external-link\" href=\"http:\/\/tech.pro\/tutorial\/855\/wcf-tutorial-basic-interprocess-communication\" rel=\"nofollow\">http:\/\/tech.pro\/tutorial\/855\/wcf-tutorial-basic-interprocess-communication<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I have made a GUI in C#. Now I want to create an API to use in vba to ease automation and make use of the team&#8217;s existing vba code. This guide gives a basic example of how to do that. Examples I found online were overly complicated and\/or not so useful. This short guide&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[8,7],"class_list":["post-41","post","type-post","status-publish","format-standard","hentry","category-dev","tag-net","tag-c"],"_links":{"self":[{"href":"http:\/\/maxwellmckinnon.com\/blog\/wp-json\/wp\/v2\/posts\/41","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/maxwellmckinnon.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/maxwellmckinnon.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/maxwellmckinnon.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/maxwellmckinnon.com\/blog\/wp-json\/wp\/v2\/comments?post=41"}],"version-history":[{"count":6,"href":"http:\/\/maxwellmckinnon.com\/blog\/wp-json\/wp\/v2\/posts\/41\/revisions"}],"predecessor-version":[{"id":56,"href":"http:\/\/maxwellmckinnon.com\/blog\/wp-json\/wp\/v2\/posts\/41\/revisions\/56"}],"wp:attachment":[{"href":"http:\/\/maxwellmckinnon.com\/blog\/wp-json\/wp\/v2\/media?parent=41"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/maxwellmckinnon.com\/blog\/wp-json\/wp\/v2\/categories?post=41"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/maxwellmckinnon.com\/blog\/wp-json\/wp\/v2\/tags?post=41"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}