I'm using access 2007 and this behaviour can be replicated as follows.
1) Create new access database accdb file.
2) Open database and create new vba module.
3) Create 1st subroutine sub1:
Sub sub1()
Msgbox Err.Description
End Sub
4) Create 2nd subroutine sub2:
Sub sub2(Description as String)
Msgbox Description
End Sub
At this point everything is normal.
5) But if I go and change sub2 so that 'Description' reads 'description', i.e. change 'D' to 'd' like so:
Sub sub2(description as String)
Msgbox description
End Sub
This also has a knock-on effect and changes sub1 too! So that sub1 now reads:
Sub sub1()
Msgbox Err.description
End Sub
Why has 'Err.Description' changed to 'Err.description' ?
This behaviour seems to have no effect on the actual functionality of the code, so no problem there. The big issue I have is that I'm exporting my vba modules as text files and putting them under SVN control. And just recently a whole load of pointless 'changes' have been committed to the repository because of this.
Any ideas on how to stop this from happening?
Sorry. That is a hard-coded "feature" of VBA. See similar question here: How does one restore default case to a variable in VBA (Excel 2010)?
The way I've worked around that with source control is to run my repository through a script that does the following:
Revert all modified files with vba code extensions (creating backup .orig files)
Do a case-insensitive compare of the .orig files to their counterparts
If there are no changes (outside of case changes) delete the .orig file
For the remaining .orig files (the ones with actual changes) delete the counterpart file and remove the .orig extension
What this does is effectively hide files where the only changes are to the case (a constant problem when working with VBA files, as you're experiencing). It does not hide case changes in a file that has had other modifications done to it. It's far from a perfect solution but it's the best I've come up with.
Additionally remember that in VBA, variable names are not case sensitive. So Description and description are the same within the same scope.
Related
I have a query in my MS ACCESS database that yields:
event (in this case, a goanna has been photographed)
photo name (e.g., IMG_0002.JPG)
path to file (e.g., c:\documents\random_place)
In the form I have built, I added a button, and built this event:
Private Sub Command17_Click()
Application.FollowHyperlink "C:\Documents\random_place\IMG_0002.JPG"
End Sub
No problem.
But what I really want is to populate the path to the file with information returned by the query (as opposed to having typed it in manually), since button I have there is static, and now all the events show photo IMG_0002.JPG, where in fact different records have different file names and even paths.
I guess I am looking for something like:
Application.FollowHyperlink paste{result from path},{result from filename}
if you see what I mean...
Assuming the query you mention is the form's RecordSource, code can reference fields/controls to build the file path\name in the button click event.
FollowHyperlink Me![path to file] & "\" & Me![photo name]
I have a coding project in MS Access. There are some developers coding and checking in the source-code to a SVN-Server.
As a SVN-Server is for managing code, it recognizes changes in the source-code files.
In these source-code-files there is a problem. VBA often changes uppercase and lowercase letters and we have no clue why.
When I do a commit it is i.e
'two examples
Call myfunction(txtNodeID)
rst![Username] = Environ("USERNAME")
Another developer updates his repository and uses my code and it changes to
'two examples
Call myfunction(txtNodeId)
rst![UserName] = Environ("USERNAME")
SVN recognizes this as a change. So we have many changed files although the logic did not change but Access modified uppercase and lowercase.
Does anyone know why Access is acting like this and how to prevent this?
Thank you.
The VBA editor should enforce variable name case to be the same as the declared variable name. This means, you should be unable to write the following:
Dim someID As String
someId = "5"
It does the same with functions. So ENVIRON becomes Environ.
However, this can get weird if you don't enforce variable declaration (no Option Explicit at the top). Then the editor will have a hard time knowing which is the correct case, and tend to change everything to the first occurrence.
The solution is to get all devs to use Option Explicit, so each variable is explicitly declared and the VBA editor knows which is the correct case (and there are many additional advantages). To avoid quirks, they should also make the edited line loses focus before saving (that's when the check happens, so you can do this wrong if you really want to. If you do, it can change to the correct case when touched).
The txtNodeID is changed to txtNodeId, because the latter is declared in the program somehow. Try this piece:
Sub TestMe()
someVariable = 5
End Sub
Then write on another module only Public SOMEVARIABLE. The TestMe sub would look like this now:
Sub TestMe()
SOMEVARIABLE = 5
End Sub
I'm playing around with splitting access databases. It appears that each table contains a hard link to the backend file in the linked table manager.
But if I wanted to send the file pair to someone through email to look at, the hard links will break. Right now we're at separate offices just testing changes to the program. This isn't in production. I don't want them to get into the development mode and edit the linked table manager because it would be too hard.
Is there a way to tell access to simply look in the front end file's directory for the backend file? Is there a way to force a prompt on the front end to let them choose the location of the backend file?
Thanks!
The simple solution is to on startup check if the table link(s) point to the current directory, and if not, then you run re-link code. That way the pair of files will work if you move the pair to a different folder or re-name the folder.
The above is a common setup and EVEN recommend for single user applications that SHOULD be split and benefit by being split.
So on startup, check the path of a linked table. I use the following code to return the path of currently linked tables.
Function strBackEndPath() As String
' returns the path name to the back end
' and includes tralinig \
Dim mytables As TableDef
Dim strTempBack As String
Dim strFullPath As String
strFullPath = ""
For Each mytables In CurrentDb.TableDefs
If Left(mytables.Connect, 10) = ";DATABASE=" Then
strFullPath = Mid(mytables.Connect, 11)
Exit For
End If
Next mytables
strBackEndPath = Left(strFullPath, InStrRev(strFullPath, "\"))
End Function
With above, then on startup I can go:
If CurrentProject.path & "\" <> strBackEndPath Then
' call re-link code
End If
And there are TONS of re-link code examples floating around but here is a link to some re-linking code.
http://access.mvps.org/access/tables/tbl0009.htm
Thus if the links don’t point to the back end database in the same folder, then re-linking will ONLY occur once and after that only the above “test” to ensure that front end and back end are are linked.
If the folder is renamed or as noted a user moves the files to a different location then again the re-link will occur.
Right-click on the front-end tables and select Linked Table Manager. From there, you can browse for the location of the back-end tables
In a data validation form, I have a subroutine checking previously-entered data on a LostFocus event by ensuring that the release time (TimeReleased in table; Me.txtTimeReleased on form) is after the capture time (ObservationTime in table; Me.txtObservationTime on form). I'm using LostFocus rather than BeforeUpdate because the data were bulk-imported into the db and are now being error-checked.
My users keep getting a compile error (Compile Error: method or data member not found) upon tabbing out of the field this sub is attached to but I cannot reproduce the problem locally. The error occurs on this line:
If (Me.txtTimeReleased) <= (Me.ObservationTime) Then
and the part highlighted is '.txtTimeReleased'
Full code block:
Private Sub txtTimeReleased_LostFocus()
Dim badData As Variant
Dim resp As Variant
'Also check that time released is after time captured
If Not IsNull(Me.txtObservationTime) And Not IsNull(Me.txtTimeReleased) Then
If (Me.txtTimeReleased) <= (Me.ObservationTime) Then
resp = MsgBox("Release time must be after capture time." & vbCrLf & "Please double check this field's value: is it correct?", _
vbYesNo + vbExclamation + vbDefaultButton2, "Release Time Before Capture Time")
If resp <> vbYes Then badData = True
End If
End If
If badData = True Then
Me.cmbTaxonId.SetFocus 'set focus away so can set focus back
With Me.txtTimeReleased
.SetFocus
.SelStart = 0
.SelLength = 10
End With
End If
End Sub
Other things to note:
Both the table field and form control are formatted as 'Short Time' (24-hour time)
There is an input mask on that form control for 24-hour time; I use input masks very rarely and thus aren't familiar with them--perhaps the input mask could be causing the problem?
There are similar LostFocus subs on most of the other controls which do not produce this (or any other) error
Things I've tried:
Checking spelling
Fully decompling and recompiling the code: starting with shift, compact and repair with shift, open with /decompile flag while holding shift, compact and repair with shift, re-open with shift, and finally compile (without error)
Replacing the form in their database with one that works fine for me on the same data
Google
Things that seem odd to me:
I can't reproduce the error locally.
The error is triggering on the second instance of
Me.txtTimeReleased rather than the first: it has already passed a Not
IsNull(Me.txtTimeReleased) check.
The fact that it's a compile error: could that be masking something else?
Thanks for your time, and please let me know if there's any additional information that would be useful. Any thoughts are most welcome!
You checked for Null txtObservationTime and txtTimeReleased, but compare then txtTimeReleased and ObservationTime. Maybe solution is:
If Not IsNull(Me.txtObservationTime) And Not IsNull(Me.txtTimeReleased) Then
If (Me.txtTimeReleased) <= (Me.txtObservationTime) Then
Opening the .mdb with the /decompile flag is one of the first things I would have suggested, but you said you already tried that.
Here's another undocumented trick to deal with "hidden" compile problems that get baked in by VBA behind the scenes:
First, make a backup copy of your .mdb just to be safe (this is, after all, an undocumented technique).
Then, save your form to a text file using SaveAsText:
SaveAsText acForm, "MyFormName", "C:\MyFormName.txt"
Finally, re-load your form using the equally undocumented LoadFromText:
LoadFromText acForm, "MyFormName", "C:\MyFormName.txt"
Compile.
Compact.
Repair.
Hope for the best.
Good luck.
I suggest you use variables:
intThat = Me.txtTimeReleased
If intThis <= intThat Then
Try using ! instead of a dot:
intThat = Me!txtTimeReleased
If intThis <= intThat Then
And now, the answer that worked for me last week:
Comment out the offending line.
Run a compile that is successful.
Restore the offending line.
The compile may work now. Don't ask me why.
Ive just inherited an MS Access 2003 system and need a bit of VBA to put behind a command button to open MyComputer at a specific folder to view the files there.
The folder name will come from a field on a form.
I did have
Application.FollowHyperLink "C:\" & Me![ref] (ref is in the format abcd-1234)
when its hard-coded it works fine, but i cant seem to get it to open when picking the foldername up from the form.
any hints? (other than binning access!)
thanks
See what the text looks like as you're submitting it to FollowHyperlink. You can insert a line like this in your code:
MsgBox "C:\" & Me![ref]
Perhaps it's not what you expect. It's always good to check.
What happens when it doesn't work. Do you see any error messages or any other symptoms which could help us nail this down?
My first thought was spaces in a folder name might create problems. But I don't think that's the answer because FollowHyperlink works fine for me in this example:
Application.FollowHyperlink "C:\Access\spaces in name\"
So the best I can offer is to see what you're asking FollowHyperlink to use. If that effort doesn't lead you to the answer, add a specific example which fails to your question.
This code always work for me:
Dim filePath = <"Insert the path of the directory to open inside of opening and closing parenthesis">
Application.FollowHyperlink filePath, vbNormalFocus
Normally, I store a few directories in a table inside the DBMS, which helps when linking hundreds of images to a database instead of embedding. For instance, I have a table called, "dbLocations." Inside this table, there are only two fields: 1) picLocation 2) Description.
The field picLocation has the value of the network path, i.e, C:\My Documents or G:\Whatever Directory or \\groups1\for UNC paths.
The field Description is what it implies, a description of the picLocation.
I use tables to store directory locations because they linking to files (.jpg, .png) stored on a network drive. As time evolves, directories can get changed (I move a folder to another location, or if the UNC changes, etc.).
If you hard code the location(s) over several subs or modules, you will need to change each one; which is very inefficient. So, in order to save time and a lot of headaches, I use the Domain Lookup function which allows me to only change the file location just once and in an easy to find place, namely, the dbLocations table.
In essence, I am looking up the value of the location inside the table where the picLocation matches the description of, Alert Pics. (I am creating a database that will be used to track Trespassers and other vagrant persons for work)
Dim filePath as String
filePath = DLookup("picLocation", "dbLocations", "[Description] = 'Alert Pics'")
Application.FollowHyperlink filePath, vbNormalFocus
With these three lines of simple code, you can navigate to a specific directory.