Consuming Web Services from Excel 2003

It's possible to consume web services from Excel 2003, but few of the sources seem to cover the topic from end-to-end. This post is intended as a companion to an O'Reilly article on the topic and includes a few elements I found necessary to get it all working.

Here's the web method we're going to consume:

[WebMethod (Description="Retrieve the production volume for a given year and region. Returns a single integer.")]
public System.Xml.XmlDocument GetVolume(int year, string
region)
{
    System.Xml.XmlDocument xd = new
System.Xml.XmlDocument();
    xd.LoadXml("<root><volume>" + MyNamespace.GetVolume().ToString() + "</volume></root>");
    return
xd;
}

The MyNamespace.GetVolume method returns a single value which I then pad with a descriptive tag (volume) and a root tag (root). Without the root tag I kept seeing a "root element is missing" error from the VB, and figured it meant my resultset was empty, not that it was looking for an actual element named "root." Note to people who write error messages for a living: concise is nice unless you write error messages for a living. Just two more characters and this could have read "<root> element is missing."

This is the code-behind for the button-click event from the Excel spreadsheet:

Public Sub GetVolume()

Dim objVolumeCalc As clsws_VolumeCalc
Set objVolumeCalc = New clsws_VolumeCalc
Dim lngVolume As Long
Dim objRange As Excel.Range

Application.ActiveSheet.Range("A2").Activate
Do
    If Application.ActiveCell.Value = "" Then
        Exit Do
    Else
        lngVolume = 0
        lngVolume = objVolumeCalc.wsm_GetVolume(Application.ActiveCell.Value, "CAN").Item(0).Text

        Set objRange = Application.ActiveCell.Offset(ColumnOffset:=1)
        objRange.Value = lngVolume
        objRange.Activate
        Set objRange = Application.ActiveCell.Offset(RowOffset:=1, ColumnOffset:=-1)
        objRange.Activate
    End If
Loop

End Sub

The companion article shows how to install and use the Office 2003 Web Services Toolkit to create the web service reference. This creates a proxy class in your VB code-behind to make the web service calls. The next frustrating error I received was "argument not optional." At that time my WS call looked like this:

lngVolume = objVolumeCalc.wsm_GetVolume(Application.ActiveCell.Value, "CAN")

The question being, "which argument is missing?" It was apparently the argument for the item specifier I hadn't yet added:

        lngVolume = objVolumeCalc.wsm_GetVolume(Application.ActiveCell.Value, "CAN").Item(0).Text

Happily, the string is auto-basically converted to a long, and getting this line right was the final trick to getting the spreadsheet working. What does the rest do? Well, it uses the values from cell A2 on down to populate the cells from cell B2 on down with the results of the web service calls. This code came from an article that is now otherwise outdated.

 The end-result is a form with a button that looks something like this:

Screen snippet of Excel consuming a web service

Published Friday, July 22, 2005 6:33 PM by erobillard
Filed under: ,

Comments

Monday, July 25, 2005 4:53 PM by Ben Adams

# re: Consuming Web Services from Excel 2003

very interesting, thanks
Friday, January 04, 2008 9:46 PM by John Reilly

# re: Consuming Web Services from Excel 2003

Although I haven't verified this, I believe the error message that you got was probably correct.  I've never seen a root element with text inside it - I think the root element must contain elements.

Wednesday, March 12, 2008 1:23 AM by kayal

# re: Consuming Web Services from Excel 2003

Its working fine in same machine. When i try to access the same excelsheet in another machine, its not working.<i have installed web service toolkit in that machine also>

Friday, April 18, 2008 11:02 AM by dimas

# re: Consuming Web Services from Excel 2003

Actually the error message IS correct - it is looking for root element, ANY root element, not just <root>. If your XML will be <notroot>...</notroot> it will work equally well.

Leave a Comment

(required) 
(required) 
(optional)
(required)