├── .gitattributes
├── .gitignore
├── Fundamentals
├── ArgumentTypeBasics
│ ├── ArgumentTypeBasics.sln
│ ├── ArgumentTypeBasics.vbproj
│ ├── ArgumentTypeBasics.xlsm
│ ├── Functions.vb
│ └── README.md
└── RibbonBasics
│ ├── Functions.vb
│ ├── My Project
│ ├── Application.Designer.vb
│ ├── Application.myapp
│ ├── AssemblyInfo.vb
│ ├── Resources.Designer.vb
│ ├── Resources.resx
│ ├── Settings.Designer.vb
│ └── Settings.settings
│ ├── README.md
│ ├── Ribbon.vb
│ ├── RibbonBasics.sln
│ ├── RibbonBasics.vbproj
│ ├── RibbonFromResources.md
│ └── RibbonResources
│ ├── MagicWand.png
│ ├── Ribbon.xml
│ ├── RibbonResources.Designer.vb
│ └── RibbonResources.resx
├── GettingStarted
└── InstallVisualStudio.md
├── README.md
├── SpecialTopics
├── DynamicArrays
│ ├── ArrayMap.cs
│ ├── ArrayResizer.cs
│ ├── DynamicArrays.csproj
│ ├── DynamicArrays.sln
│ ├── ExampleFunctions.cs
│ ├── Examples.xlsx
│ └── README.md
├── IntelliSenseForVBAFunctions
│ ├── README.md
│ ├── TempFunctions.IntelliSense.xml
│ ├── TempFunctions.xlsm
│ └── TempFunctionsWithDescriptions.xlsm
└── RTD
│ ├── README.md
│ └── TimerRTD
│ ├── DataSources.cs
│ ├── Functions.cs
│ ├── RtdServer.cs
│ ├── TimerRTD.csproj
│ └── TimerRTD.sln
├── Testing
├── README.md
└── TestingSample
│ ├── Sample.Test
│ ├── ExcelTests.cs
│ ├── Sample.Test.csproj
│ └── TestBook.xlsx
│ ├── Sample
│ ├── Functions.cs
│ └── Sample.csproj
│ └── TestingSample.sln
└── VBA-to-.NET
├── FormulaEvaluateConvert
├── FormulaEvaluate.sln
├── FormulaEvaluate
│ ├── FormulaEvaluate.vbproj
│ ├── My Project
│ │ ├── Application.Designer.vb
│ │ ├── Application.myapp
│ │ ├── AssemblyInfo.vb
│ │ ├── Resources.Designer.vb
│ │ ├── Resources.resx
│ │ ├── Settings.Designer.vb
│ │ ├── Settings.settings
│ │ └── launchSettings.json
│ ├── Test.xlsx
│ ├── clsMathParser.vb
│ ├── mExcelHelpers.vb
│ ├── mExcelMacros.vb
│ ├── mFunHelpers.vb
│ └── mMathSpecFun.vb
├── FormulaEvaluateConvert.md
└── OriginalFiles
│ ├── Analisis Numerico y Macros en Excel.xlsm
│ ├── clsMathParser.cls
│ ├── mExcelMacros.bas
│ └── mMathSpecFun.bas
├── Readme.md
└── WebRequestBasics
└── Readme.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Build results
17 | [Dd]ebug/
18 | [Dd]ebugPublic/
19 | [Rr]elease/
20 | [Rr]eleases/
21 | x64/
22 | x86/
23 | [Aa][Rr][Mm]/
24 | [Aa][Rr][Mm]64/
25 | bld/
26 | [Bb]in/
27 | [Oo]bj/
28 | [Ll]og/
29 |
30 | # Visual Studio 2015/2017 cache/options directory
31 | .vs/
32 | # Uncomment if you have tasks that create the project's static files in wwwroot
33 | #wwwroot/
34 |
35 | # Visual Studio 2017 auto generated files
36 | Generated\ Files/
37 |
38 | # MSTest test Results
39 | [Tt]est[Rr]esult*/
40 | [Bb]uild[Ll]og.*
41 |
42 | # NUNIT
43 | *.VisualState.xml
44 | TestResult.xml
45 |
46 | # Build Results of an ATL Project
47 | [Dd]ebugPS/
48 | [Rr]eleasePS/
49 | dlldata.c
50 |
51 | # Benchmark Results
52 | BenchmarkDotNet.Artifacts/
53 |
54 | # .NET Core
55 | project.lock.json
56 | project.fragment.lock.json
57 | artifacts/
58 |
59 | # StyleCop
60 | StyleCopReport.xml
61 |
62 | # Files built by Visual Studio
63 | *_i.c
64 | *_p.c
65 | *_h.h
66 | *.ilk
67 | *.meta
68 | *.obj
69 | *.iobj
70 | *.pch
71 | *.pdb
72 | *.ipdb
73 | *.pgc
74 | *.pgd
75 | *.rsp
76 | *.sbr
77 | *.tlb
78 | *.tli
79 | *.tlh
80 | *.tmp
81 | *.tmp_proj
82 | *_wpftmp.csproj
83 | *.log
84 | *.vspscc
85 | *.vssscc
86 | .builds
87 | *.pidb
88 | *.svclog
89 | *.scc
90 |
91 | # Chutzpah Test files
92 | _Chutzpah*
93 |
94 | # Visual C++ cache files
95 | ipch/
96 | *.aps
97 | *.ncb
98 | *.opendb
99 | *.opensdf
100 | *.sdf
101 | *.cachefile
102 | *.VC.db
103 | *.VC.VC.opendb
104 |
105 | # Visual Studio profiler
106 | *.psess
107 | *.vsp
108 | *.vspx
109 | *.sap
110 |
111 | # Visual Studio Trace Files
112 | *.e2e
113 |
114 | # TFS 2012 Local Workspace
115 | $tf/
116 |
117 | # Guidance Automation Toolkit
118 | *.gpState
119 |
120 | # ReSharper is a .NET coding add-in
121 | _ReSharper*/
122 | *.[Rr]e[Ss]harper
123 | *.DotSettings.user
124 |
125 | # JustCode is a .NET coding add-in
126 | .JustCode
127 |
128 | # TeamCity is a build add-in
129 | _TeamCity*
130 |
131 | # DotCover is a Code Coverage Tool
132 | *.dotCover
133 |
134 | # AxoCover is a Code Coverage Tool
135 | .axoCover/*
136 | !.axoCover/settings.json
137 |
138 | # Visual Studio code coverage results
139 | *.coverage
140 | *.coveragexml
141 |
142 | # NCrunch
143 | _NCrunch_*
144 | .*crunch*.local.xml
145 | nCrunchTemp_*
146 |
147 | # MightyMoose
148 | *.mm.*
149 | AutoTest.Net/
150 |
151 | # Web workbench (sass)
152 | .sass-cache/
153 |
154 | # Installshield output folder
155 | [Ee]xpress/
156 |
157 | # DocProject is a documentation generator add-in
158 | DocProject/buildhelp/
159 | DocProject/Help/*.HxT
160 | DocProject/Help/*.HxC
161 | DocProject/Help/*.hhc
162 | DocProject/Help/*.hhk
163 | DocProject/Help/*.hhp
164 | DocProject/Help/Html2
165 | DocProject/Help/html
166 |
167 | # Click-Once directory
168 | publish/
169 |
170 | # Publish Web Output
171 | *.[Pp]ublish.xml
172 | *.azurePubxml
173 | # Note: Comment the next line if you want to checkin your web deploy settings,
174 | # but database connection strings (with potential passwords) will be unencrypted
175 | *.pubxml
176 | *.publishproj
177 |
178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
179 | # checkin your Azure Web App publish settings, but sensitive information contained
180 | # in these scripts will be unencrypted
181 | PublishScripts/
182 |
183 | # NuGet Packages
184 | *.nupkg
185 | # The packages folder can be ignored because of Package Restore
186 | **/[Pp]ackages/*
187 | # except build/, which is used as an MSBuild target.
188 | !**/[Pp]ackages/build/
189 | # Uncomment if necessary however generally it will be regenerated when needed
190 | #!**/[Pp]ackages/repositories.config
191 | # NuGet v3's project.json files produces more ignorable files
192 | *.nuget.props
193 | *.nuget.targets
194 |
195 | # Microsoft Azure Build Output
196 | csx/
197 | *.build.csdef
198 |
199 | # Microsoft Azure Emulator
200 | ecf/
201 | rcf/
202 |
203 | # Windows Store app package directories and files
204 | AppPackages/
205 | BundleArtifacts/
206 | Package.StoreAssociation.xml
207 | _pkginfo.txt
208 | *.appx
209 |
210 | # Visual Studio cache files
211 | # files ending in .cache can be ignored
212 | *.[Cc]ache
213 | # but keep track of directories ending in .cache
214 | !?*.[Cc]ache/
215 |
216 | # Others
217 | ClientBin/
218 | ~$*
219 | *~
220 | *.dbmdl
221 | *.dbproj.schemaview
222 | *.jfm
223 | *.pfx
224 | *.publishsettings
225 | orleans.codegen.cs
226 |
227 | # Including strong name files can present a security risk
228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
229 | #*.snk
230 |
231 | # Since there are multiple workflows, uncomment next line to ignore bower_components
232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
233 | #bower_components/
234 |
235 | # RIA/Silverlight projects
236 | Generated_Code/
237 |
238 | # Backup & report files from converting an old project file
239 | # to a newer Visual Studio version. Backup files are not needed,
240 | # because we have git ;-)
241 | _UpgradeReport_Files/
242 | Backup*/
243 | UpgradeLog*.XML
244 | UpgradeLog*.htm
245 | ServiceFabricBackup/
246 | *.rptproj.bak
247 |
248 | # SQL Server files
249 | *.mdf
250 | *.ldf
251 | *.ndf
252 |
253 | # Business Intelligence projects
254 | *.rdl.data
255 | *.bim.layout
256 | *.bim_*.settings
257 | *.rptproj.rsuser
258 | *- Backup*.rdl
259 |
260 | # Microsoft Fakes
261 | FakesAssemblies/
262 |
263 | # GhostDoc plugin setting file
264 | *.GhostDoc.xml
265 |
266 | # Node.js Tools for Visual Studio
267 | .ntvs_analysis.dat
268 | node_modules/
269 |
270 | # Visual Studio 6 build log
271 | *.plg
272 |
273 | # Visual Studio 6 workspace options file
274 | *.opt
275 |
276 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
277 | *.vbw
278 |
279 | # Visual Studio LightSwitch build output
280 | **/*.HTMLClient/GeneratedArtifacts
281 | **/*.DesktopClient/GeneratedArtifacts
282 | **/*.DesktopClient/ModelManifest.xml
283 | **/*.Server/GeneratedArtifacts
284 | **/*.Server/ModelManifest.xml
285 | _Pvt_Extensions
286 |
287 | # Paket dependency manager
288 | .paket/paket.exe
289 | paket-files/
290 |
291 | # FAKE - F# Make
292 | .fake/
293 |
294 | # JetBrains Rider
295 | .idea/
296 | *.sln.iml
297 |
298 | # CodeRush personal settings
299 | .cr/personal
300 |
301 | # Python Tools for Visual Studio (PTVS)
302 | __pycache__/
303 | *.pyc
304 |
305 | # Cake - Uncomment if you are using it
306 | # tools/**
307 | # !tools/packages.config
308 |
309 | # Tabs Studio
310 | *.tss
311 |
312 | # Telerik's JustMock configuration file
313 | *.jmconfig
314 |
315 | # BizTalk build output
316 | *.btp.cs
317 | *.btm.cs
318 | *.odx.cs
319 | *.xsd.cs
320 |
321 | # OpenCover UI analysis results
322 | OpenCover/
323 |
324 | # Azure Stream Analytics local run output
325 | ASALocalRun/
326 |
327 | # MSBuild Binary and Structured Log
328 | *.binlog
329 |
330 | # NVidia Nsight GPU debugger configuration file
331 | *.nvuser
332 |
333 | # MFractors (Xamarin productivity tool) working folder
334 | .mfractor/
335 |
336 | # Local History for Visual Studio
337 | .localhistory/
338 |
339 | # BeatPulse healthcheck temp database
340 | healthchecksdb
341 | /Fundamentals/ArgumentTypeBasics/My Project/launchSettings.json
342 |
--------------------------------------------------------------------------------
/Fundamentals/ArgumentTypeBasics/ArgumentTypeBasics.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30517.126
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ArgumentTypeBasics", "ArgumentTypeBasics.vbproj", "{DE0E5693-45DE-414F-BD36-E2BB27566EAD}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {DE0E5693-45DE-414F-BD36-E2BB27566EAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {DE0E5693-45DE-414F-BD36-E2BB27566EAD}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {DE0E5693-45DE-414F-BD36-E2BB27566EAD}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {DE0E5693-45DE-414F-BD36-E2BB27566EAD}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {5D3363B5-4857-41B1-BF46-BD7009A586D5}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/Fundamentals/ArgumentTypeBasics/ArgumentTypeBasics.vbproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net472;net6.0-windows
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Fundamentals/ArgumentTypeBasics/ArgumentTypeBasics.xlsm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Excel-DNA/Tutorials/975040aa8c64ed489603a4ef2ee28ef31421e08b/Fundamentals/ArgumentTypeBasics/ArgumentTypeBasics.xlsm
--------------------------------------------------------------------------------
/Fundamentals/ArgumentTypeBasics/Functions.vb:
--------------------------------------------------------------------------------
1 | Imports ExcelDna.Integration
2 |
3 | Public Module Functions
4 |
5 | ' Provides information about the data type and value that is passed in as argument
6 | Public Function dnaArgumentInfo(arg As Object) As String
7 |
8 | If TypeOf arg Is ExcelMissing Then
9 | Return "<>"
10 | ElseIf TypeOf arg Is ExcelEmpty Then
11 | Return "<>"
12 | ElseIf TypeOf arg Is Double Then
13 | Return "Double: " & CDbl(arg)
14 | ElseIf TypeOf arg Is String Then
15 | Return "String: " & CStr(arg)
16 | ElseIf TypeOf arg Is Boolean Then
17 | Return "Boolean: " & CBool(arg)
18 | ElseIf TypeOf arg Is ExcelError Then
19 | Return "ExcelError: " & arg.ToString()
20 | ElseIf TypeOf arg Is Object(,) Then
21 | ' The object array returned here may contain a mixture of different types,
22 | ' corresponding to the different cell contents.
23 | ' Arrays received will always be 0-based 2D arrays
24 | Dim argArray(,) As Object = arg
25 | Return String.Format("Array({0},{1})", argArray.GetLength(0), argArray.GetLength(1))
26 | Else
27 | Return "!? Unheard Of ?!"
28 | End If
29 |
30 | End Function
31 |
32 |
33 | ' Adding the AllowReference:=True flag means we can also accept sheet references
34 | Public Function dnaArgumentInfoAllowRef( arg As Object) As String
35 |
36 | If TypeOf arg Is ExcelReference Then
37 | Dim argRef As ExcelReference = arg
38 |
39 | ' We could construct a COM Range object from the ExcelReference if we needed to access some of the Range information
40 | ' For now we just read the values, and call the normal description function to describe the values at the sheet reference
41 | Return "Reference " & argRef.ToString() & ": " & dnaArgumentInfo(argRef.GetValue())
42 | Else
43 | Return dnaArgumentInfo(arg)
44 | End If
45 |
46 | End Function
47 |
48 | ' The parameter type is declared as a 2D array.
49 | ' The function can take a single value, or any rectangular range as input.
50 | ' Union references with multiple areas will only pass in the first area
51 | Public Function dnaSumEvenNumbers2D(arg(,) As Object) As Double
52 |
53 | Dim sum As Double = 0
54 | Dim rows As Integer
55 | Dim cols As Integer
56 |
57 | rows = arg.GetLength(0)
58 | cols = arg.GetLength(1)
59 |
60 | For i As Integer = 0 To rows - 1
61 | For j As Integer = 0 To cols - 1
62 |
63 | Dim val As Object = arg(i, j)
64 | If val Mod 2 = 0 Then
65 | sum += val
66 | End If
67 |
68 | Next
69 | Next
70 |
71 | Return sum
72 |
73 | End Function
74 |
75 | ' The parameter type is declared as a 1D array.
76 | ' The function can take a single value, a single row or a single column
77 | ' If a 2D range with more than one row and column is passed in, only the first row will be passed in here
78 | Public Function dnaSumEvenNumbers1D(arg() As Object) As Double
79 |
80 | Dim sum As Double = 0
81 | Dim val As Object
82 |
83 | For Each val In arg
84 | If val Mod 2 = 0 Then
85 | sum += val
86 | End If
87 | Next
88 |
89 | Return sum
90 |
91 | End Function
92 |
93 | ' The parameter type is declared as a 1D double array.
94 | ' If the values passed in cannot be converted to numbers, Excel will return a #VALUE! error to the sheet
95 | Public Function dnaSumEvenNumbersDouble1D(arg() As Double) As Double
96 |
97 | Dim sum As Double = 0
98 |
99 | For i As Integer = 0 To arg.Length - 1 ' Alternative to `For Each ...` for going through the array
100 |
101 | Dim val As Object = arg(i)
102 | If val Mod 2 = 0 Then
103 | sum += val
104 | End If
105 |
106 | Next
107 |
108 | Return sum
109 |
110 | End Function
111 |
112 | ' The parameter type is declared as a 2D double array.
113 | ' If the values passed in cannot be converted to numbers, Excel will return a #VALUE! error to the sheet
114 | Public Function dnaSumEvenNumbersDouble2D(arg(,) As Double) As Double
115 |
116 | Dim sum As Double = 0
117 | Dim rows As Integer
118 | Dim cols As Integer
119 |
120 | rows = arg.GetLength(0)
121 | cols = arg.GetLength(1)
122 |
123 | For i As Integer = 0 To rows - 1
124 | For j As Integer = 0 To cols - 1
125 |
126 | Dim val As Object = arg(i, j)
127 | If val Mod 2 = 0 Then
128 | sum += val
129 | End If
130 |
131 | Next
132 | Next
133 |
134 | Return sum
135 |
136 | End Function
137 |
138 | ' The parameter type is declared as Object, and marked with the AllowReference:=True flag
139 | ' The function can take a single value, or any sheet reference as input
140 | ' Sheet references might be to union ranges with multiple areas, which we process individually
141 | Public Function dnaSumEvenNumbersR( arg As Object)
142 | Dim sum As Double
143 |
144 | If TypeOf arg Is ExcelReference Then
145 |
146 | ' To be really careful, we get the 2D array of values from each of the areas in the reference
147 | ' This lets the function suppport union ranges as input correctly
148 | Dim argRef As ExcelReference = arg
149 | For Each rect In argRef.InnerReferences
150 | sum += dnaSumEvenNumbers2D(rect.GetValue())
151 | Next
152 | ElseIf TypeOf arg Is Object(,) Then
153 | ' We can call the array implementation directly
154 | sum = dnaSumEvenNumbers2D(arg)
155 | Else
156 | ' Just check and return the value
157 | If arg Mod 2 = 0 Then
158 | sum = arg
159 | End If
160 | End If
161 | Return sum
162 | End Function
163 |
164 | End Module
165 |
--------------------------------------------------------------------------------
/Fundamentals/RibbonBasics/Functions.vb:
--------------------------------------------------------------------------------
1 | Imports ExcelDna.Integration
2 |
3 | Public Module MyFunctions
4 |
5 |
6 | Public Function HelloDna(name As String) As String
7 | Return "Hello " & name
8 | End Function
9 |
10 | End Module
--------------------------------------------------------------------------------
/Fundamentals/RibbonBasics/My Project/Application.Designer.vb:
--------------------------------------------------------------------------------
1 | '------------------------------------------------------------------------------
2 | '
3 | ' This code was generated by a tool.
4 | ' Runtime Version:4.0.30319.42000
5 | '
6 | ' Changes to this file may cause incorrect behavior and will be lost if
7 | ' the code is regenerated.
8 | '
9 | '------------------------------------------------------------------------------
10 |
11 | Option Strict On
12 | Option Explicit On
13 |
14 |
--------------------------------------------------------------------------------
/Fundamentals/RibbonBasics/My Project/Application.myapp:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 | false
5 | 0
6 | true
7 | 0
8 | 1
9 | true
10 |
11 |
--------------------------------------------------------------------------------
/Fundamentals/RibbonBasics/My Project/AssemblyInfo.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Reflection
3 | Imports System.Runtime.InteropServices
4 |
5 | ' General Information about an assembly is controlled through the following
6 | ' set of attributes. Change these attribute values to modify the information
7 | ' associated with an assembly.
8 |
9 | ' Review the values of the assembly attributes
10 |
11 | '
12 |
13 | '
14 | '
15 |
16 |
17 |
18 |
19 |
20 | 'The following GUID is for the ID of the typelib if this project is exposed to COM
21 |
22 |
23 | ' Version information for an assembly consists of the following four values:
24 | '
25 | ' Major Version
26 | ' Minor Version
27 | ' Build Number
28 | ' Revision
29 | '
30 | ' You can specify all the values or you can default the Build and Revision Numbers
31 | ' by using the '*' as shown below:
32 | '
33 |
34 | '
35 | '
36 |
--------------------------------------------------------------------------------
/Fundamentals/RibbonBasics/My Project/Resources.Designer.vb:
--------------------------------------------------------------------------------
1 | '------------------------------------------------------------------------------
2 | '
3 | ' This code was generated by a tool.
4 | ' Runtime Version:4.0.30319.42000
5 | '
6 | ' Changes to this file may cause incorrect behavior and will be lost if
7 | ' the code is regenerated.
8 | '
9 | '------------------------------------------------------------------------------
10 |
11 | Option Strict On
12 | Option Explicit On
13 |
14 |
15 | Namespace My.Resources
16 |
17 | 'This class was auto-generated by the StronglyTypedResourceBuilder
18 | 'class via a tool like ResGen or Visual Studio.
19 | 'To add or remove a member, edit your .ResX file then rerun ResGen
20 | 'with the /str option, or rebuild your VS project.
21 | '''
22 | ''' A strongly-typed resource class, for looking up localized strings, etc.
23 | '''
24 | _
28 | Friend Module Resources
29 |
30 | Private resourceMan As Global.System.Resources.ResourceManager
31 |
32 | Private resourceCulture As Global.System.Globalization.CultureInfo
33 |
34 | '''
35 | ''' Returns the cached ResourceManager instance used by this class.
36 | '''
37 | _
38 | Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
39 | Get
40 | If Object.ReferenceEquals(resourceMan, Nothing) Then
41 | Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("RibbonBasics.Resources", GetType(Resources).Assembly)
42 | resourceMan = temp
43 | End If
44 | Return resourceMan
45 | End Get
46 | End Property
47 |
48 | '''
49 | ''' Overrides the current thread's CurrentUICulture property for all
50 | ''' resource lookups using this strongly typed resource class.
51 | '''
52 | _
53 | Friend Property Culture() As Global.System.Globalization.CultureInfo
54 | Get
55 | Return resourceCulture
56 | End Get
57 | Set(ByVal value As Global.System.Globalization.CultureInfo)
58 | resourceCulture = value
59 | End Set
60 | End Property
61 | End Module
62 | End Namespace
63 |
--------------------------------------------------------------------------------
/Fundamentals/RibbonBasics/My Project/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/Fundamentals/RibbonBasics/My Project/Settings.Designer.vb:
--------------------------------------------------------------------------------
1 | '------------------------------------------------------------------------------
2 | '
3 | ' This code was generated by a tool.
4 | ' Runtime Version:4.0.30319.42000
5 | '
6 | ' Changes to this file may cause incorrect behavior and will be lost if
7 | ' the code is regenerated.
8 | '
9 | '------------------------------------------------------------------------------
10 |
11 | Option Strict On
12 | Option Explicit On
13 |
14 |
15 | Namespace My
16 |
17 | _
20 | Partial Friend NotInheritable Class MySettings
21 | Inherits Global.System.Configuration.ApplicationSettingsBase
22 |
23 | Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings)
24 |
25 | #Region "My.Settings Auto-Save Functionality"
26 | #If _MyType = "WindowsForms" Then
27 | Private Shared addedHandler As Boolean
28 |
29 | Private Shared addedHandlerLockObject As New Object
30 |
31 | _
32 | Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs)
33 | If My.Application.SaveMySettingsOnExit Then
34 | My.Settings.Save()
35 | End If
36 | End Sub
37 | #End If
38 | #End Region
39 |
40 | Public Shared ReadOnly Property [Default]() As MySettings
41 | Get
42 |
43 | #If _MyType = "WindowsForms" Then
44 | If Not addedHandler Then
45 | SyncLock addedHandlerLockObject
46 | If Not addedHandler Then
47 | AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
48 | addedHandler = True
49 | End If
50 | End SyncLock
51 | End If
52 | #End If
53 | Return defaultInstance
54 | End Get
55 | End Property
56 | End Class
57 | End Namespace
58 |
59 | Namespace My
60 |
61 | _
64 | Friend Module MySettingsProperty
65 |
66 | _
67 | Friend ReadOnly Property Settings() As Global.RibbonBasics.My.MySettings
68 | Get
69 | Return Global.RibbonBasics.My.MySettings.Default
70 | End Get
71 | End Property
72 | End Module
73 | End Namespace
74 |
--------------------------------------------------------------------------------
/Fundamentals/RibbonBasics/My Project/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Fundamentals/RibbonBasics/README.md:
--------------------------------------------------------------------------------
1 | # Ribbon Basics
2 |
3 | In this tutorial we will add a ribbon extension to an Excel-DNA add-in.
4 | The Office ribbon extensions are defined in an .xml markup format which we will add to the project.
5 | Then we define a class to process the ribbon callback methods, to react to commands like a button press.
6 |
7 | For this tutorial I will use a Visual Basic add-in; everything works similar in a C# project.
8 |
9 | There are some more advanced topics not covered in this tutorial:
10 | * Show how to change or enable elements of the interface based on some internal state.
11 | * Request a ribbon interface update from an event handler or external trigger.
12 | * Compare the native ribbon interface we use here, with the high-level wrapper provided by VSTO.
13 | * Explain internals of how the ribbon implementation works in Excel-DNA.
14 |
15 | ## Prepare
16 |
17 | Our starting point is a simple Excel-DNA add-in that declares a single UDF as a test.
18 | To prepare the environment for working on the ribbon extensions, we add two steps.
19 |
20 | 1. Install XML schemas (optional)
21 |
22 | To get IntelliSense help for the ribbon extension, we can either
23 | * install the `Excel-DNA XML Schemas` extension to Visual Studio, or
24 | * install the `ExcelDna.XmlSchemas` package in our add-in.
25 |
26 | The first approach requires admin permissions on the machine, but has the advantage of not adding any extra files to the project and only being done once.
27 |
28 | 2. Configure Excel to show interface errors (optional)
29 |
30 | Excel has a setting to display any errors in interface extensions like the ribbon. Enabling this settings is a great help while developing a ribbon extension.
31 | It can be found under **Tools -> Options -> Advanced: Show add-in user interface errors**.
32 |
33 | 
34 |
35 | ## Add the ribbon xml markup
36 |
37 | We now add a new `.xml` file to the project, which we will add to the .dna configuration file. This approach allows us to easily edit the .xml file in Visual Studio and is good for a simple add-in. Two other options for locating the same xml information are:
38 | * Put the xml text inline in the ribbon handler class.
39 | * Put the xml content in a separate file embedded in a resource.
40 |
41 | For more complicated add-ins, I prefer putting keeping the xml content in a separate file because it is easier to edit, and does not clutter the .dna file.
42 | But for this example I will take the simple approach with the ribbon markup inside the .dna file.
43 |
44 | Edit the `-AddIn.dna` file, and add the following markup under the `` tag:
45 |
46 | ```xml
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | ```
61 |
62 | Note that there are two nested tags called `` and `` respectively.
63 |
64 | ## Add the Ribbon handler code
65 |
66 | Now we add code to handle the ribbon callback - in our example the button has an `onAction='OnSayHelloPressed'` attribute.
67 | So we need:
68 | * a class that derives from the `ExcelRibbon` base class, marked as `` and
69 | * a method called `OnSayHelloPressed` with the right signature to handle the `onAction` callback for a `button`.
70 |
71 | To implement this, add a new class to the project, with this content:
72 |
73 | ```vb
74 | Imports System.Runtime.InteropServices
75 | Imports ExcelDna.Integration.CustomUI
76 |
77 |
78 | Public Class Ribbon
79 | Inherits ExcelRibbon
80 |
81 | Public Sub OnSayHelloPressed(control As IRibbonControl)
82 | MsgBox("Hello from .NET!")
83 | End Sub
84 |
85 | End Class
86 | ```
87 |
88 | We can now build and run the add-in, to test the new ribbon.
89 |
90 | ## Interact with the Excel COM object model
91 |
92 | Typically you would run some macro command form the ribbon handler, which would interact with the Excel COM object model similar to a VBA macro.
93 |
94 | ### Reference the Excel COM interop assemblies
95 |
96 | First, we add a reference to the COM interop assemblies to our add-in. This will allow us to easily use the Excel COM object model from our add-in.
97 | To do this, add the NuGet package 'ExcelDna.Interop' to the project. It would also be possible to reference the COM libraries directly.
98 |
99 | The `ExcelDna.Interop` package includes the Excel 2010 version of the COM object model. This means an add-in that uses these features should work under any Excel 2010 and later versions. However, newer features are not available.
100 |
101 | ### Add macro code to the ribbon callback
102 |
103 | In the Excel-DNA case, this means we need to get hold of the root Application object with a call to `ExcelDnaUtil.Application`.
104 | From there we can use the object model in a similar way to VBA.
105 |
106 | Modify the example like this:
107 |
108 | ```vb
109 | ' Add these namespace imports at the top of the file
110 | Imports Microsoft.Office.Interop.Excel
111 | Imports ExcelDna.Integration
112 |
113 | ' And then change the method like this
114 |
115 | Public Sub OnSayHelloPressed(control As IRibbonControl)
116 | Dim app As Application
117 | Dim rng As Range
118 |
119 | app = ExcelDnaUtil.Application ' This gets the root Excel Application object from the Excel-DNA environment
120 | rng = app.Range("A1") ' Get a Range object for cell A1 on the ActiveSheet
121 |
122 | rng.Value = "Hello from .NET!" ' Set the value in that cell
123 | End Sub
124 |
125 | ```
126 |
127 | ## Add an image
128 |
129 | Next we add an image to display on the ribbon button.
130 |
131 | For this we adjust the markup
132 | 1. Add an image file to our project, (I put it an a project folder as `Images\MagicWand.png`) and set its `Copy to Output Directory` property to `Copy if Newer`. That ensures the image file will be available when debugging.
133 | 2. Add a `loadImage` callback to the `customUI` tag. Excel-DNA internally implements the `LoadImage` method on the `ExcelRibbon` base class.
134 | 3. Add an `image` attribute to the `button` to select the image.
135 | 4. Add an `Image` tag in the .dna file to identify and pack the image file, with the `Path` pointing to the location - in this case I've put it under an Images folder in the project, so I'll use `Path='Images\MagicWand.png`. I also add `Pack='true'` so that the image file will be included in the packed .xll file.
136 |
137 | The .dna file gets these changes:
138 |
139 | ```xml
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 | ```
158 |
159 | Now build and run to see the image added to the button in Excel.
160 |
161 | ## Ribbon xml and callback documentation
162 |
163 | Excel-DNA is responsible for loading the ribbon helper add-in, but is not otherwise involved in the ribbon extension. This means that the custom UI xml schema, and the signatures for the callback methods are exactly as documented by Microsoft. The best documentation for these aspects can be found in the three-part series on 'Customizing the 2007 Office Fluent Ribbon for Developers':
164 |
165 | * [Part 1 - Overview](https://msdn.microsoft.com/en-us/library/aa338202.aspx)
166 | * [Part 2 - Controls and callback reference](https://msdn.microsoft.com/en-us/library/aa338199.aspx)
167 | * [Part 3 - Frequently asked questions, including C# and VB.NET callback signatures](https://msdn.microsoft.com/en-us/library/aa722523.aspx)
168 |
169 | Information related to the Excel 2010 extensions to the ribbon can be found here:
170 |
171 | * [Customizing Context Menus in Office 2010](https://msdn.microsoft.com/en-us/library/office/ee691832.aspx)
172 | * [Customizing the Office 2010 Backstage View](https://msdn.microsoft.com/en-us/library/office/ee815851.aspx)
173 | * [Ribbon Extensibility in Office 2010: Tab Activation and Auto-Scaling](https://msdn.microsoft.com/en-us/library/office/ee691834.aspx)
174 |
--------------------------------------------------------------------------------
/Fundamentals/RibbonBasics/Ribbon.vb:
--------------------------------------------------------------------------------
1 | Imports System.Runtime.InteropServices
2 | Imports Microsoft.Office.Interop.Excel
3 | Imports ExcelDna.Integration.CustomUI
4 | Imports ExcelDna.Integration
5 | Imports RibbonBasics.My.Resources
6 |
7 |
8 | Public Class Ribbon
9 | Inherits ExcelRibbon
10 |
11 | Public Overrides Function GetCustomUI(RibbonID As String) As String
12 | Return RibbonResources.Ribbon ' The name here is the resource name that the ribbon xml has in the RibbonResources resource file
13 | End Function
14 |
15 | Public Overrides Function LoadImage(imageId As String) As Object
16 | ' This will return the image resource with the name specified in the image='xxxx' tag
17 | Return RibbonResources.ResourceManager.GetObject(imageId)
18 | End Function
19 | Public Sub OnSayHelloPressed(control As IRibbonControl)
20 | Dim app As Application
21 | Dim rng As Range
22 |
23 | app = ExcelDnaUtil.Application
24 | rng = app.Range("A1")
25 | rng.Value = "Hello from .NET!"
26 |
27 | End Sub
28 |
29 | End Class
30 |
--------------------------------------------------------------------------------
/Fundamentals/RibbonBasics/RibbonBasics.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30517.126
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "RibbonBasics", "RibbonBasics.vbproj", "{BC64C7ED-B1ED-4FF3-B286-041CC9D400FE}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {BC64C7ED-B1ED-4FF3-B286-041CC9D400FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {BC64C7ED-B1ED-4FF3-B286-041CC9D400FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {BC64C7ED-B1ED-4FF3-B286-041CC9D400FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {BC64C7ED-B1ED-4FF3-B286-041CC9D400FE}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {B64813DD-EEAE-429C-AEBE-D08ED5A7CFA5}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/Fundamentals/RibbonBasics/RibbonBasics.vbproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net472;net6.0-windows
4 | true
5 |
6 |
7 |
8 | PreserveNewest
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | True
18 | True
19 | RibbonResources.resx
20 |
21 |
22 |
23 |
24 | My.Resources
25 | ResXFileCodeGenerator
26 | RibbonResources.Designer.vb
27 |
28 |
29 |
--------------------------------------------------------------------------------
/Fundamentals/RibbonBasics/RibbonFromResources.md:
--------------------------------------------------------------------------------
1 | # Project layout with ribbon and images in a resources file
2 |
3 |
4 | An alternative approach is to add the .xml file in a separate file and embed as a resource in the add-in.
5 | For complicated projects, this might be a better structure.
6 |
7 | I'll put the ribbon xml file and related resources (like images we show in the ribbon) into a project folder called `RibbonResources`.
8 |
9 | Steps to add the `.xml` file as a resource:
10 | 1. Add a new folder under our project to hold our ribbon resources - called e.g. `RibbonResources`
11 | 2. Add a new xml file called `Ribbon.xml` with the following content inside the `RibbonResources` folder:
12 |
13 | ```xml
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | ```
27 |
28 | 3. Add a new resources file to the project called `RibbonResources.resx`.
29 | 4. Into the resource file, `Add Existing File` and select the `RibbonResouces\Ribbon.xml` file. Check that it is called `Ribbon` - we'll use this name a bit later.
30 |
31 | 5. Take similar steps for an image, where the name of the image in the resources file matches the name in the `image` attribute in the ribbon markup.
32 |
33 | 6. The class will now explicitly get the ribbon markup and images from the resources class. It does this my overriding the `GetCustomUI` and `LoadImage` methods of the `ExcelRibbon` base class.
34 |
35 | ```vb
36 | Imports System.Runtime.InteropServices
37 | Imports ExcelDna.Integration.CustomUI
38 |
39 |
40 | Public Class Ribbon
41 | Inherits ExcelRibbon
42 |
43 | Public Overrides Function GetCustomUI(RibbonID As String) As String
44 | Return RibbonResources.Ribbon ' The name here is the resource name that the ribbon xml has in the RibbonResources resource file
45 | End Function
46 |
47 | Public Overrides Function LoadImage(imageId As String) As Object
48 | ' This will return the image resource with the name specified in the image='xxxx' tag
49 | Return RibbonResources.ResourceManager.GetObject(imageId)
50 | End Function
51 |
52 | Public Sub OnButtonPressed(control As IRibbonControl)
53 | MsgBox("Hello")
54 | End Sub
55 |
56 | End Class
57 | ```
58 |
--------------------------------------------------------------------------------
/Fundamentals/RibbonBasics/RibbonResources/MagicWand.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Excel-DNA/Tutorials/975040aa8c64ed489603a4ef2ee28ef31421e08b/Fundamentals/RibbonBasics/RibbonResources/MagicWand.png
--------------------------------------------------------------------------------
/Fundamentals/RibbonBasics/RibbonResources/Ribbon.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Fundamentals/RibbonBasics/RibbonResources/RibbonResources.Designer.vb:
--------------------------------------------------------------------------------
1 | '------------------------------------------------------------------------------
2 | '
3 | ' This code was generated by a tool.
4 | ' Runtime Version:4.0.30319.42000
5 | '
6 | ' Changes to this file may cause incorrect behavior and will be lost if
7 | ' the code is regenerated.
8 | '
9 | '------------------------------------------------------------------------------
10 |
11 | Option Strict On
12 | Option Explicit On
13 |
14 | Imports System
15 |
16 | Namespace My.Resources
17 |
18 | 'This class was auto-generated by the StronglyTypedResourceBuilder
19 | 'class via a tool like ResGen or Visual Studio.
20 | 'To add or remove a member, edit your .ResX file then rerun ResGen
21 | 'with the /str option, or rebuild your VS project.
22 | '''
23 | ''' A strongly-typed resource class, for looking up localized strings, etc.
24 | '''
25 | _
28 | Friend Class RibbonResources
29 |
30 | Private Shared resourceMan As Global.System.Resources.ResourceManager
31 |
32 | Private Shared resourceCulture As Global.System.Globalization.CultureInfo
33 |
34 | _
35 | Friend Sub New()
36 | MyBase.New
37 | End Sub
38 |
39 | '''
40 | ''' Returns the cached ResourceManager instance used by this class.
41 | '''
42 | _
43 | Friend Shared ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
44 | Get
45 | If Object.ReferenceEquals(resourceMan, Nothing) Then
46 | Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("RibbonBasics.RibbonResources", GetType(RibbonResources).Assembly)
47 | resourceMan = temp
48 | End If
49 | Return resourceMan
50 | End Get
51 | End Property
52 |
53 | '''
54 | ''' Overrides the current thread's CurrentUICulture property for all
55 | ''' resource lookups using this strongly typed resource class.
56 | '''
57 | _
58 | Friend Shared Property Culture() As Global.System.Globalization.CultureInfo
59 | Get
60 | Return resourceCulture
61 | End Get
62 | Set
63 | resourceCulture = value
64 | End Set
65 | End Property
66 |
67 | '''
68 | ''' Looks up a localized resource of type System.Drawing.Bitmap.
69 | '''
70 | Friend Shared ReadOnly Property MagicWand() As System.Drawing.Bitmap
71 | Get
72 | Dim obj As Object = ResourceManager.GetObject("MagicWand", resourceCulture)
73 | Return CType(obj,System.Drawing.Bitmap)
74 | End Get
75 | End Property
76 |
77 | '''
78 | ''' Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?>
79 | '''<customUI xmlns='http://schemas.microsoft.com/office/2009/07/customui' loadImage='LoadImage'>
80 | ''' <ribbon>
81 | ''' <tabs>
82 | ''' <tab id='tab1' label='My Tab'>
83 | ''' <group id='group1' label='My Group'>
84 | ''' <button id='button1' label='My Button' onAction='OnButtonPressed' image='MagicWand'/>
85 | ''' </group>
86 | ''' </tab>
87 | ''' </tabs>
88 | ''' </ribbon>
89 | '''</customUI>.
90 | '''
91 | Friend Shared ReadOnly Property Ribbon() As String
92 | Get
93 | Return ResourceManager.GetString("Ribbon", resourceCulture)
94 | End Get
95 | End Property
96 | End Class
97 | End Namespace
98 |
--------------------------------------------------------------------------------
/Fundamentals/RibbonBasics/RibbonResources/RibbonResources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | MagicWand.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
123 |
124 |
125 | Ribbon.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8
126 |
127 |
--------------------------------------------------------------------------------
/GettingStarted/InstallVisualStudio.md:
--------------------------------------------------------------------------------
1 | # Install Visual Studio
2 |
3 | [Visual Studio](https://visualstudio.microsoft.com) is the integrated development environment (IDE) used to develop .NET application and libraries, including Excel-DNA add-ins developed with .NET. I've made a step-by-step video guide that you can find on YouTube.
4 |
5 | [](http://www.youtube.com/watch?v=M-9jsOXVw_o "Excel-DNA - Install Visual Studio")
6 |
7 | Some notes are below.
8 |
9 | ### Notice the different 'Visual Studio' products and editions
10 |
11 | We are interested in the 'Visual Studio' product, and can then select one of the three editions to install.
12 |
13 | 
14 |
15 | Any of the three editions can be used for Excel-DNA developement.
16 | The Community and Professional editions have the same functionality, but differ in the cost and license restrictions. The Community edition is free but have limitation on use in Enterprise environments.
17 | [Details about Visual Studio editions](https://visualstudio.microsoft.com/vs/compare)
18 |
19 | ### Select the workload during installation
20 |
21 | During Visual Studio installation the main selection concerns the workloads and components to be installed.
22 |
23 | 
24 |
25 | For Excel-DNA development we require only the *.NET Desktop Development* workload to be installed. All the optional features may be deselected. Also note tate the *Office/Sharepoint tools* workload in not required for doing Excel-DNA development.
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Tutorials
2 | Tutorial content and sample projects for Excel-DNA.
3 |
4 | ## Contents
5 |
6 | ### GettingStarted
7 | * [Installing Visual Studio](GettingStarted/InstallVisualStudio.md)
8 |
9 | ### Fundamentals
10 | * [UDF Argument Types in VBA and .NET](Fundamentals/ArgumentTypeBasics)
11 | * [Ribbon Basics](Fundamentals/RibbonBasics)
12 |
13 | ### Special Topics
14 | * [Dynamic Arrays](SpecialTopics/DynamicArrays)
15 | * [IntelliSense for VBA Functions](SpecialTopics/IntelliSenseForVBAFunctions)
16 | * [RTD](SpecialTopics/RTD)
17 |
18 | ### Testing
19 | * [Testing Helper Introduction](Testing)
20 |
21 | ## Topic ideas
22 | * All about arrays
23 | * IntelliSense inside and out
24 | * VBA to DNA (and back again)
25 | * Dealing with a deluge of data
26 |
--------------------------------------------------------------------------------
/SpecialTopics/DynamicArrays/ArrayMap.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ExcelDna.Integration;
3 | using static ExcelDna.Integration.XlCall;
4 |
5 | public static class ArrayMapFunctions
6 | {
7 | // This helper function is converted from https://github.com/Excel-DNA/Samples/blob/master/ArrayMap/Functions.vb
8 | [ExcelFunction(Description = "Evaluates the two-argument function for every value in the first and second inputs. " + "Takes a single value and any rectangle, or one row and one column, or one column and one row.")]
9 | public static object dnaArrayMap2([ExcelArgument(Description = "The function to evaluate - either enter the name without any quotes or brackets (for .xll functions), or as a string (for VBA functions)")] object function, [ExcelArgument(Description = "The input value(s) for the first argument (row, column or rectangular range) ")] object input1, [ExcelArgument(Description = "The input value(s) for the second argument (row, column or rectangular range) ")] object input2)
10 | {
11 | {
12 | Func