VSTO & .NET & Excel

March 29, 2012

VLOOKUP Week; Using VLOOKUP in VB

Filed under: .NET & Excel, COM Add-ins, Excel, VSTO & Excel, XLLs — Dennis M Wallentin @ 3:49 pm

Bill Jelen, MrExcel, has marked this week to honor the VLOOKUP function in MS Excel. Around the online Excel development community You will find contributions, usually blog posts, that gives various aspects for using or not VLOOKUP.

I thought it would be interesting to create a case and see how VLOOKUP can be part of  VB-solutions. Actually, for several years ago I did similar solutions but with classic VB (VB6) for a customer. Imagine that we have a price list for our products. Because of the frequent price updates the company has decided to store it in a MS Excel workbook. To keep it very simple for the sales staff they use a standalone VB-solution where they select products, retrieve the price for each product item and add some additional information manually to get a total price.

As most Excel developers should know, we can acquire data from workbooks in several ways. The most common approach is to treat the workbook as a flat database table. Technically we either use classic ADO or DAO to connect to the database table and using a SQL query to get the wanted records. This is a smooth solution but it assumes that the ADO/DAO library is available on all computers that will use the solutions. To avoid a situation where we must check if the library is installed or not we can use a solution where we automate Excel and execute the VLOOKUP function to get the wanted data. Practical we get a robust solution that is not depended on ADO/DAO and when working with small data sets the performance is fully acceptable.

The following screen shot shows how the price list workbook looks like:

As we can see it’s a simple table that is manually updated.

The next screen shot shows the VB-solution in action. The product list is picked up from a storage system. Sales person starts to select the products he/she wants to calculate the prices for, retrieve the prices, add number of items and then get a total price per product. The total prices including freight etc. is done in another part of the VB-solutions:

As You can see it’s a simple tool to work with. The last piece of the solution is the code I use to retrieve the prices and populate the DatagridView with.

The following code is in use and is executed when clicking on the Get Price button control:

Imports Excel = Microsoft.Office.Interop.Excel
Imports System.Runtime.InteropServices

Public Class Form1

Private Sub btnVLOOKUP_Click(sender As System.Object, e As System.EventArgs) _
Handles btnVLOOKUP.Click

Dim Location As String = Environment.GetEnvironmentVariable("USERPROFILE") _
.ToString() + "\Documents\Product Lists\"

Dim File As String = "'" + Location + "[P_List_2011.xlsx]ProductList'!R1C2:R78C3,2,0"

Dim itemChecked As Object

If Me.CheckedListBox1.CheckedItems.Count = 0 Then
MessageBox.Show("Please select at least one product.")
Exit Sub
End If

Dim xlApp As New Excel.Application

Try

For Each itemChecked In Me.CheckedListBox1.CheckedItems

Dim Price As String = String.Empty

'Here we do the lookup based on the selected product name.
Price = xlApp.ExecuteExcel4Macro("VLOOKUP(""" + itemChecked.ToString() _
+ """," + File + ")")

Dim rowValues As String() = New String() {itemChecked.ToString, Price.ToString}

'Add the row with data to the data grid,
Me.dgwPList.Rows.Add(rowValues)
Me.dgwPList.Columns(0).AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells

Next

Catch ex As Exception

MessageBox.Show(ex.ToString())

Finally

xlApp.Quit()

End Try

'Cleaning up.
If Not xlApp Is Nothing Then
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForPendingFinalizers()
xlApp.Quit()
End If

Marshal.FinalReleaseComObject(xlApp)

End Sub

Edit: I intentionally used the XLM macro program to show that we can still use it and with VB.NET. I thought that someone would point out that it can also be done by using xlApp.WorksheetFunction.VLookup. My friend Ken Puls, ExcelGuru, finally pointed it out.
Kind regards,
Dennis

March 19, 2012

Remove Duplicates in VB

Filed under: .NET & Excel, COM Add-ins, Excel, VSTO & Excel — Dennis M Wallentin @ 3:42 pm

I have some articles in the pipeline that shows how to achieve various tasks in MS Excel with VB.NET. It’s no rocket science but practical solutions for frequent tasks. The first article is this that covers how to remove duplicates from tables.

To following screen shot shows the table before removing any duplicates:

In the solution I will use columns 1,3,4 and 5 in the list to filter out the duplicates and than remove them.

The following code shows the VB solution. The method RemoveDuplicate expect that the column’s indexes are temporarily stored in an object array (Similar to worksheets’ collections).

Imports Excel = Microsoft.Office.Interop.Excel
Imports System.Runtime.InteropServices

Public Class Form1

Private Sub C1Button2_Click(sender As System.Object, e As System.EventArgs) _
Handles C1Button2.Click

'Excel's objects.
Dim xlApp As New Excel.Application
Dim xlWBook As Excel.Workbook = xlApp.Workbooks.Open( _
Filename:="C:\Users\Dennis Wallentin\Documents\RemDupes.xlsx")

Dim xlSheet As Excel.Worksheet = CType(xlWBook.Worksheets(1),  _
Excel.Worksheet)
Dim xlRange As Excel.Range = xlSheet.Range("A1:E7")

'The Object Array that will hold the columns numbers when executing
'the instruction.
Dim oColumnsToUse(0) As Object

'The default value for the parameter Header is XlNo.
Dim Header As Microsoft.Office.Interop.Excel.XlYesNoGuess

'Populate the Object Array with column's numbers.
oColumnsToUse.SetValue(1, 0) 'Col 1
oColumnsToUse.SetValue(3, 0) 'Col 3
oColumnsToUse.SetValue(4, 0) 'Col 4
oColumnsToUse.SetValue(5, 0) 'Col 5

'Removes all duplicates.
xlRange.RemoveDuplicates(Columns:=oColumnsToUse, Header:=Header)

'Save and close the workbook.
xlWBook.Close(SaveChanges:=vbYes)

'Cleaning up.
If Not xlApp Is Nothing Then
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForPendingFinalizers()
xlApp.Quit()
End If

Marshal.FinalReleaseComObject(xlRange)
Marshal.FinalReleaseComObject(xlSheet)
Marshal.FinalReleaseComObject(xlWBook)
Marshal.FinalReleaseComObject(xlApp)

End Sub

After executing the above code we will have a list that looks like the following:

Kind regards,
Dennis

March 2, 2012

Add-in Express vs Visual Studio Tools for Office (VSTO)

Filed under: .NET & Excel, COM Add-ins, Excel, Tools, VSTO & Excel — Tags: , , — Dennis M Wallentin @ 12:15 am

I recently stoped by at Add-in Express and noticed an interesting series of articles that compare their RAD-tool with VSTO. You may read themselves at the following URLs:

Enjoy!

Kind regards,
Dennis

Blog at WordPress.com.