Any one else noticed this?
Thats a Major revision number, that should mean there’s been some significant updates should it not? Anyone seen any, I’ve haven’t!
Any one else noticed this?
Thats a Major revision number, that should mean there’s been some significant updates should it not? Anyone seen any, I’ve haven’t!
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]
Private Sub GetData(dbName As String, sYear As String)
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Set cn = New ADODB.Connection
cn.Open “Provider=Microsoft.Jet.OLEDB.4.0; Data Source=” & dbName & “;”
Set rs = New ADODB.Recordset
Dim qdf As New ADODB.Command
qdf.ActiveConnection = cn
qdf.CommandText = “SELECT * FROM [Some_Query];”
qdf.Parameters.Append qdf.CreateParameter(“Forms!Billing!Combo8″, adVarChar, adParamInput, 1, “”)
qdf.Parameters(0) = (“*”)
qdf.Parameters.Append qdf.CreateParameter(“Forms!Billing!Combo12″, adVarChar, adParamInput, 1, “”)
qdf.Parameters(1) = (“*”)
qdf.Parameters.Append qdf.CreateParameter(“Forms!Billing!Combo18″, adVarChar, adParamInput, 1, “”)
qdf.Parameters(2) = (“*”)
qdf.Parameters.Append qdf.CreateParameter(“Forms!Billing!Combo14″, adVarChar, adParamInput, 1, “”)
qdf.Parameters(3) = (“*”)
qdf.Parameters.Append qdf.CreateParameter(“Forms!Billing!Combo16″, adVarChar, adParamInput, 4, “”)
qdf.Parameters(4) = (sYear)
qdf.Parameters.Append qdf.CreateParameter(“Forms!Billing!Combo6″, adVarChar, adParamInput, 1, “”)
qdf.Parameters(5) = (“*”)
Set rs = qdf.Execute
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
End sub
[/vba]
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]
Sub GetData(ByVal Year As String, ByVal FullFilePath As String)
Dim qdf As QueryDef
Dim rst As Recordset
Set qdf = CurrentDb.QueryDefs(“final charges by project period and person”)
qdf.Parameters(0) = “*”
qdf.Parameters(1) = “*”
qdf.Parameters(2) = “*”
qdf.Parameters(3) = “*”
qdf.Parameters(4) = sYear
qdf.Parameters(5) = “*”
Set rst = qdf.OpenRecordset
‘Make Text File
Dim F As Integer
Dim I As Integer
F = FreeFile
Open sFullFilePath For Output As #F
‘Print Columns’ Headers
For I = 1 To rst.Fields.Count
Print #F, rst.Fields(I – 1).Name & “,”;
Next I
Print #F,
‘Print Data
Do While Not rst.EOF
For I = 1 To rst.Fields.Count
Print #F, rst.Fields(I – 1).Value & “,”;
Next I
Print #F,
rst.MoveNext
Loop
Close (F)
rst.Close
qdf.Close
Set rst = Nothing
Set qdf = Nothing
End Sub
[/vba]
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.
You can customise the shape of your user forms, and it’s Kewl! All the kids in my house are doing it! Look at this stupid form shape I was able to make!
Why on earth would you want to do it I hear you ask?! That’s a very good question! When I started this I thought it was really not very useful at all. I’m still thinking that, but maybe there might be a few practical uses for it. I’m thinking tool tips and popup type things. I have covered using captionless user forms (and worksheets!), and even popup forms previously. I was never happy with the way the captionless forms looked in VBA, they look ok in VB6 but in VBA they has a wafty boarder.
Of course if you want to move over to VSTO you can even make a user form in the shape of John Walkenbach’s upper half! Is that the sound of ringing tills I can hear!
Release.zip (Excel 2007 only + .Net 3/3.5)
There is no keyword in VB6 that allows you to set the default value of a class. Code like this for example will error out.
[VBA]
Public Sub Test()
Dim x As New MyClass
x.Name = “Ross”
x.Name2 = “Dave”
MsgBox x
End Sub
[/VBA]
However it can be done, even if it’s a bit of a pain! Export the class and add the following code in note pad, as the first line under the function heading:
Attribute Name.VB_UserMemId = 0
The value must be 0, and the Attribute must be the name of the function, get, etc. you want to use as the default. The notepad file might look some thing like this!
Save the changes in notepad, in the IDE delete and re-import the class. The code will now work! Amazing! If you make any major changes to the class code you will have to redo the process, that’s the PITA bit!
“Validating” file names is one of those things that no matter how hard you try you’ll never get it 100% right. There are a loads of reasons when a file might not save, even if the name is valid, acess rights, disk space, problems with the file it’s self, network issues…
Basically you have to trust the user a bit and try to pick up any basic errors.
With that in mind I found this was the simplest, and most ‘bang for buck’ type of function to use. It’s easy and gets it right most of the time. You still need to manage errors well when you save the actual file though!!!
[vba]
Private Sub txtFileName_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If (Me.txtFileName.Text Like “*[/\:*?""<>]*”) Then
a = MsgBox(“Invalid filename format, please try another, ” _
& “Stuff like /, @, ~, ?, ! etc does not help.”, , _
gsAppName & gsAppVersion)
Me.txtFileName.SetFocus
End If
End Sub[/vba]
Here I’ve added it to the Exit event of a text box, so it runs each time the user leaves the text box. Another option would be to run the check at the end of a form, i.e when OK is pressed. You’ll have to think about which method will work best for your application.