The End Result: What We're Building
For our example, we'll imagine an Azure Function named ConvertLength that performs simple length conversions, such as from meters to feet or inches to meters. After we create our function, we'll write some VBA code in Excel to connect to it. The end result will be a custom function in Excel that, when run, executes an Azure Function in the cloud.
=ConvertLength(A1, B1, D1)
Excel function ConvertLength is executing Azure Function
Creating the Azure Function
The function we're creating, ConvertLength, is an HTTP Trigger-invoked in-portal function written in C#. ConvertLength expects 3 parameters:- value : a value to convert, such as 832
- from : a from unit of measurement, such as ft
- to: a destination unit of measurement, such as in
The result will be the value in the destination unit of measurement, such as 9984
Here is the C# code for our function:
#r "Newtonsoft.Json" using System.Net; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Primitives; using Newtonsoft.Json; public static async Task<iactionresult> Run(HttpRequest req, ILogger log) { log.LogInformation("C# HTTP trigger function processed a request."); double fromValue = Convert.ToDouble(req.Query["value"]); string fromUnits = NormalizeUnits(req.Query["from"]); // m|meter|meters, ft|foot|feet, in|inch|inches string toUnits = NormalizeUnits(req.Query["to"]); if (fromUnits=="?") { return (ActionResult)new OkObjectResult($"invalid 'from' parameter - unrecognized unit of measurement"); } if (toUnits=="?") { return (ActionResult)new OkObjectResult($"invalid 'to' parameter - unrecognized unit of measurement"); } double toValue = 0.00; switch(fromUnits) { case "m": switch(toUnits) { case "m": toValue = fromValue; break; case "ft": toValue = fromValue * 3.28084; break; case "in": toValue = fromValue * 3.28084 * 12; break; } break; case "ft": switch(toUnits) { case "ft": toValue = fromValue; break; case "in": toValue = fromValue * 12; break; case "m": toValue = fromValue * 0.3048; break; } break; case "in": switch(toUnits) { case "in": toValue = fromValue; break; case "ft": if (fromValue==0) toValue = 0.00; else toValue = fromValue / 12; break; case "m": toValue = fromValue * 0.3048; break; } break; } return (ActionResult)new OkObjectResult(toValue.ToString()); } // Normalize units to standard expected values. private static string NormalizeUnits(String units) { switch(units.ToLower()) { case "m": case "meter": case "meters": return "m"; case "ft": case "foot": case "feet": return "ft"; case "in": case "inch": case "inches": return "in"; default: return "?"; } return units; }
ConvertLength source code
We can test this in the portal, but also from a browser. Copying the function URL from the portal, here's a test in a browser:
Testing ConvertLength Azure Function in Browser
We can see the function is working. We converted 1 m = 3.28084 ft, 18 ft = 5.4864m, and 5280 ft = 63,360 inches.
Creating The Excel Function
Now that we have a working Azure Function, we need to create an Excel Function to invoke it. To do that, you'll need to get set up for VBA development in Excel. You'll need to do the following in Excel:- Activate the VBA Add-in. Open Excel, select File > Options, select Add-ins. Select Analysis ToolPack - VBA and click OK.
- Enable Access to VBA. In Excel, select File > Options, and go to Trust Center. Click Trust Center Settings and search for Macro Settings. Click the Trust access to the VBA project object model checkbox.
- Enable Developer Menu. Go to File > Options and select Customize Ribbon. On the list of Main Tabs on the right, check the Developer checkbox and click OK.
- Add References for Internet Controls. Select Tools > References from the menu, check the following and click OK: Mirosoft Internet Controls, Microsoft WinHTTP Services, Microsoft Scripting Runtime.
Right-click the VBAProject in the outline at left and select Insert Module. In the module, enter the code for the Excel ConvertLength function.
Excel VBA Code
Below is a listing of the function code. Let's walk through what it's doing:
- The function declaration is named ConvertLength and expects three string parameters: value (number we want to convert), from (the source unit of measurement), and to (the destination unit of measurement). Value will actually be a number, but the function treats everything as string for ease of putting the URL together.
- A URL is assembled: the base URL of our Azure function plus query parameters value, from, and to, whose values are the parameters passed in to the function.
- Next, MSXML2.XLHTTP is called to make an HTTP GET request using variable request.
- Lastly, the function result is th request object's ResponseText parameter.
Function ConvertLength(value As String, fromUnits As String, toUnits As String) As String Dim url As String Dim request As Object url = "https://globalization.azurewebsites.net/api/ConvertLength?value=" + value + "&from=" + fromUnits + "&to=" + toUnits Set request = CreateObject("MSXML2.XMLHTTP") With request .Open "GET", url, False .Send End With ConvertLength = request.ResponseText End Function
Excel ConvertLength VBA Code
Save the module file by clicking the disk icon at top in the VBA development environment.
Using The Function in Excel
Excel parameter values
=ConvertLength(A1, B1, D1)
Right after you press ENTER, C1 should display the converted value. Pressing ENTER caused the local Excel function code to run, which in turn invoked the Azure Function.
Now that we see how straightforward this is, we can use the function as much as wish in the spreadsheet:
No comments:
Post a Comment