Tag: VBA

The MIE Podcasts – Dick Kusleika

In the third MIE podcast I caught up with Dick Kusleika, father of the Excel blog and founder of the Dailiy Dose of Excel. We talked about his blog, his passion for the keyboard, SQL, ADO and DAO, amongst other things. Dicks sure is a nice guy, no matter what people say ;-).

Dick Kusleika, King of the Keyboard

Dick Kusleika, King of the Keyboard

Get the goodness here:

[podcast]http://mie.jellycast.com/pod/20091125 Dick Kusleika on SQL and Data.mp3[/podcast]

Please leave some comments with any feedback about this podcast, and also any ideas for future podcasts.

I'd also like to say a big thank you to the guys at Jellycast.com (Luke and NickM) for their help in getting the new hosting set up, great support guys.

Enjoy

Pop up Style Forms in Excel

Final one in the blast from the past series, a pop up type form, you probably wouldn't implement it like I've done in the example file but you get the idea!

popupform

The file can be found here: PopUpForm

64 bit VBA

In my last post, VBA Version 7  Daniel, author of Daniel's XL Toolbox, commented that he had not come across anything untoward with the “new!” version of VBA, and reported, so far, all is well with his addin – good news! Then JP from Code For Excel & Outlook, pointed to a  VBA Compatibility tool (tool, info) from MS – thanks JP, I think this is called team work! ;-)

Anyway, I believe the major update might be support of 64 bit types in VBA?  I’m not running a 64 bit OS to test, but I found this:

Excel 2010 can load much larger workbooks. Excel 2010 made updates to use 64-bit memory addressing in order to move beyond the 2-GB addressable memory boundary that limits 32-bit applications.

The down side of this is:

Visual Basic for Applications (VBA)   VBA code that uses the Declare statement to access the Windows application programming interface (API) or other DLL entry points will see differences between 32-bit and 64-bit versions. The Declare statement must be updated with the PtrSafe attribute after inputs and outputs to the API have been reviewed and updated. Declare statements will not work in 64-bit VBA without the PtrSafe attribute. New data types are added to 64-bit Office 2010 VBA: LongLong and LongPtr. For more information about VBA, see the “64-bit VBA Overview” and “Declare Statement” articles in the Microsoft Visual Basic for Applications online Help in Office applications.

So if your using API calls in you VBA, and you hit a 64 bit versions, you could be about to hit some issue. Doesn’t sound like the fix will be to hard though, but we’ll wait and see eh!

Bonus thought: Does this mean the C API has been updated too?

VBA version 7?

Any one else noticed this?

VBAversion7

Thats a Major revision number, that should mean there’s been some significant updates should it not? Anyone seen any, I’ve haven’t!

Parameters in ADO, getting good with Access – NOT!

Here’s the deal. Access database on a network share. Very, very, very complex set of queries (queries on queries on queries etc, etc). Ross, can you automate my reporting spread sheet?

So while the spreadsheet work is straight forward, the hard part here is getting the data into the spread sheet. I started off just writing some standard SQL and using ADO to pull a data set back. I soon realised, that the query had to be much more complex. In fact it was such a horrible set of logic, that I didn’t want to touch it with a barge pole!

What I thought I would try next is calling the query that the database used to produce a report, but return the dataset to my rs, and stick that in to Excel. That required the use of parameters that where getting fed into the underlying queries from a form in the database at run time. This was something I had not done with ADO before. A colleague showed me the way, basically:

VBA:
  1. Private Sub GetData(dbName As String, sYear As String)
  2.  
  3. Dim cn As ADODB.Connection
  4. Dim rs As ADODB.Recordset
  5.  
  6. Set cn = New ADODB.Connection
  7.  
  8. cn.Open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" &  dbName & ";"
  9.  
  10. Set rs = New ADODB.Recordset
  11.  
  12. Dim qdf As New ADODB.Command
  13. qdf.ActiveConnection = cn
  14. qdf.CommandText = "SELECT * FROM [Some_Query];"
  15.  
  16. qdf.Parameters.Append qdf.CreateParameter("Forms!Billing!Combo8", adVarChar, adParamInput, 1, "")
  17. qdf.Parameters(0) = ("*")
  18. qdf.Parameters.Append qdf.CreateParameter("Forms!Billing!Combo12", adVarChar, adParamInput, 1, "")
  19. qdf.Parameters(1) = ("*")
  20. qdf.Parameters.Append qdf.CreateParameter("Forms!Billing!Combo18", adVarChar, adParamInput, 1, "")
  21. qdf.Parameters(2) = ("*")
  22. qdf.Parameters.Append qdf.CreateParameter("Forms!Billing!Combo14", adVarChar, adParamInput, 1, "")
  23. qdf.Parameters(3) = ("*")
  24. qdf.Parameters.Append qdf.CreateParameter("Forms!Billing!Combo16", adVarChar, adParamInput, 4, "")
  25. qdf.Parameters(4) = (sYear)
  26. qdf.Parameters.Append qdf.CreateParameter("Forms!Billing!Combo6", adVarChar, adParamInput, 1, "")
  27. qdf.Parameters(5) = ("*")
  28.  
  29. Set rs = qdf.Execute
  30.  
  31. rs.Close
  32. Set rs = Nothing
  33. cn.Close
  34. Set cn = Nothing
  35.  
  36. End sub

This code worked!!!!  Success? Joy? The gratitude of an over worked account? Not quite.

The next snag was an Access classic “Undefined function”. The function that caused the error was MonthName, which produces a string indicating the specified month. This is not supported via DAO, so now what!?!?!

Here’s an inelegant solution. Copy the database, it’s a front end back end job, so just the UI/ reporting part; keep the linked tables and get ride of the stuff you don’t need. Add some code to call the required query in access and pass the parameters, you can do this with code like this:

VBA:
  1. Sub GetData(ByVal Year As String, ByVal FullFilePath As String)
  2.  
  3. Dim qdf As QueryDef
  4. Dim rst As Recordset
  5.  
  6. Set qdf = CurrentDb.QueryDefs("final charges by project period and person")
  7.  
  8. qdf.Parameters(0) = "*"
  9. qdf.Parameters(1) = "*"
  10. qdf.Parameters(2) = "*"
  11. qdf.Parameters(3) = "*"
  12. qdf.Parameters(4) = sYear
  13. qdf.Parameters(5) = "*"
  14.  
  15. Set rst = qdf.OpenRecordset
  16. 'Make Text File
  17.  
  18. Dim F As Integer
  19. Dim I As Integer
  20. F = FreeFile
  21. Open sFullFilePath For Output As #F
  22. 'Print Columns' Headers
  23. For I = 1 To rst.Fields.Count
  24. Print #F, rst.Fields(I - 1).Name & ",";
  25. Next I
  26. Print #F,
  27. 'Print Data
  28. Do While Not rst.EOF
  29. For I = 1 To rst.Fields.Count
  30. Print #F, rst.Fields(I - 1).Value & ",";
  31. Next I
  32. Print #F,
  33. rst.MoveNext
  34. Loop
  35. Close (F)
  36.  
  37. rst.Close
  38. qdf.Close
  39. Set rst = Nothing
  40. Set qdf = Nothing
  41. End Sub

You’ll notice that this also prints out a text file (nice!), So in Excel automate this copy of the mbd,  (which you stick on the same local PC as the excel spreadsheet, right!!!) then collect the text file in to Excel and there you have it! Perfection, no way, works, yes. Why the local copy? Well I didn’t what to “effect” the org db, and I didn’t what to automate over a slow network, I’m note sure if it’s a valid, but the thought of performing automation on a file saved on a network drive, doesn’t fill me with warm fuzzy feeling!

This may well be a contender for a WTF, but I’m WTF’d if I can think of a better way to solve the particular problem. Any ideas, ever done anything similar.