Access VBA Form_before_update event is unnecessarily triggered - vba

I have this code (in Form_Before_update Event) which checks for duplicate values in sdtCode field:
If DCount("[sdtCode]", "[tbl_sdt_Info]", "[sdtCode] = '" & Me.sdtCode.Value & "'") > 0 Then
Me.Undo
MsgBox "duplicates found"
End If
It works perfectly. However, after I use the following code to link the record to a picture, and when I try to move to another record the fisrst code is triggered and it gives me the "duplicates found" message!!!!
Private Sub sdtPicture_Click()
Dim fd As FileDialog
Dim i As Integer
Dim strSelectedPicture As Variant
Dim strExtension As String
Set fd = Application.FileDialog(msoFileDialogOpen)
With fd
.AllowMultiSelect = False
'show only set of extension file in dialog
.Filters.Clear
.Filters.Add "Image file", "*.jpeg;*.png;*.jpg;*.gif", 1
If .Show = -1 Then
For Each strSelectedPicture In .SelectedItems
For i = Len(strSelectedPicture) To 1 Step -1
If Mid(strSelectedPicture, i, 1) = "." Then
strExtension = Mid(strSelectedPicture, i)
Exit For
End If
Next i
Me.sdtImagePath.Value = strSelectedPicture
' if folder name doesnt exist then make new one
On Error Resume Next
MkDir "C:\dbImageArchive\students\"
' On Error GoTo 0
'if folder exist, copy image to distination folder
'file name in the drive C:\
FileCopy strSelectedPicture, "C:\dbImageArchive\students\" & "sdt_" & Me.sdtCode & strExtension
Me.sdtPicturePath.Value = "C:\dbImageArchive\students\" & "sdt_" & Me.sdtCode.Value & strExtension
'Add a text box (sdtPictureName) to display the name of the picture file
'Me.sdtPictureName = Me.sdtID & strExtension
Next strSelectedPicture
Else
'display when no file is selected
MsgBox "?? E?II ???C?", vbInformation, ""
End If
Set fd = Nothing
End With
Me.cboOrganizations.SetFocus
'Me.Refresh
End Sub
I tried the Form_after_update event. It produced further problems. Any ideas to solve this issue please. Thank you.

Related

File name presists in Dir() function over multiple sessions

I have some code in a Excel VBA macro and it seems like its persisting values between sessions. The issue is with the BtnUpdate_Click event, the message box doesnt trigger even if the file path in NewDataFilePath is invalid.
Public NewDataFilePath As String
Private Sub BtnFileBrowse_Click()
Dim fdlg As FileDialog
Set fdlg = Application.FileDialog(msoFileDialogOpen)
fdlg.Title = "Select New Dataset"
fdlg.Filters.Clear
fdlg.Filters.Add "Excel Files Only", "*.xls; *.xlsx"
fdlg.Show
If fdlg.SelectedItems.Count <> 0 Then
TxtFilePath = fdlg.SelectedItems(1)
End If
NewDataFilePath = TxtFilePath.Text
End Sub
Private Sub BtnUpdate_Click()
Dim a As String
a = Dir(NewDataFilePath)
If Not Dir(NewDataFilePath) <> "" Then
MsgBox """ & NewDataFilePath & "" is not a valid file path"
End If
End Sub
I added the string a in the event handler to try and debug the code and its showing me some interesting results:
I have a breakpoint on the if statement in BtnUpdate_Click.
Then i stop debugging the macro and re-run it. if i invoke BtnUpdate_Click without selecting another file the Dir() function seems to keep the last file name:
Any ideas why this could happen?
Of course there is no persistence of any variable value once you stop a macro
While the observed behavior is due to the following:
1) FileDialog object keeps the last path chosen in its IntialFileName property
2) Dir(path) function with an empty string as "path" would return the first file in the IntialFileName path stored by last FileDialog run
so when you re-run the macro:
NewDataFilePath is an empty string
a = Dir(NewDataFilePath), would return the first file in the IntialFileName path matching the filters (if any)
What above as the answer to your question
While you could consider the following "nuance" of your code:
Private Sub BtnUpdate_Click()
If NewDataFilePath <> "" Then 'if 'NewDataFilePath' has been set
Dim a As String
a = Dir(NewDataFilePath)
If Not Dir(NewDataFilePath) <> "" Then MsgBox """ & NewDataFilePath & "" is not a valid file path"
Else 'otherwise
MsgBox "No file path specified!", vbCritical ' inform the user to do so
End If
End Sub
Try this code
Public NewDataFilePath As String
Private Sub BtnFileBrowse_Click()
Dim fdlg As FileDialog
Set fdlg = Application.FileDialog(msoFileDialogOpen)
fdlg.Title = "Select New Dataset"
fdlg.Filters.Clear
fdlg.Filters.Add "Excel Files Only", "*.xls; *.xlsx"
fdlg.Show
If fdlg.SelectedItems.Count <> 0 Then
NewDataFilePath = fdlg.SelectedItems(1)
End If
End Sub
Private Sub BtnUpdate_Click()
Dim a As String
a = Dir(NewDataFilePath)
If DoesFileExist(NewDataFilePath) And NewDataFilePath <> "" Then
MsgBox NewDataFilePath & " is a valid file path"
Else
MsgBox NewDataFilePath & " NOT a valid file path"
End If
End Sub
Function DoesFileExist(filePath) As Boolean
DoesFileExist = Dir(filePath) <> ""
End Function

End If in Access VBA giving me fits

I keep getting an error in this code saying "End If without Block If". I've looked at it and can't see the problem, printed it out and connected all the If statements to their joining End If, and everything looks right.
Is something else throwing e off, like that With/End With block?
Private Sub cmd__Import_Eligibility_Click()
' Requires reference to Microsoft Office 11.0 Object Library.
Dim fDialog As FileDialog
Dim varFile As Variant
Dim filelen As Integer
Dim filename As String
Dim tblname As String
' Set up the File Dialog.
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
fDialog.InitialFileName = "oo*.*"
With fDialog
' Set the title of the dialog box.
.Title = "Please select a file"
' Clear out the current filters, and add our own.
.Filters.Clear
.Filters.Add "Excel Spreadsheets", "*.xls*"
.Filters.Add "Comma Separated", "*.CSV"
.Filters.Add "All Files", "*.*"
' Show the dialog box. If the .Show method returns True, the
' user picked at least one file. If the .Show method returns
' False, the user clicked Cancel.
If .Show = True Then
'Loop through each file selected and add it to our list box.
varFile = fDialog.SelectedItems(1)
If Right(varFile, 4) = ".xls" Or Right(varFile, 5) = ".xlsx" Then
'get only file name
For a = Len(varFile) To 1 Step -1
If Mid(varFile, 1) = "\" Then
filelen = a
End If
Exit For
filename = Right(varFile, filelen)
tblname = Left(filename, InStr(filename, ".") - 1)
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12, tblname, filename, True
End If 'ERRORS OUT ON THIS LINE ==========================
Else
MsgBox "You clicked Cancel in the file dialog box."
End If
End With
End Sub
As Scott posted as a comment, your For...Next loop construct is malformed:
For a = Len(varFile) To 1 Step -1
If Mid(varFile, 1) = "\" Then
filelen = a
End If
Exit For
There's no such thing as a For...Exit For loop. You mean to do this:
For a = Len(varFile) To 1 Step -1
If Mid(varFile, 1) = "\" Then
filelen = a
Exit For
End If
Next
Otherwise the compiler is seeing [roughly] this:
If [bool-expression] Then
For [for-loop-setup]
If [bool-expression] Then
[instructions]
End If
Exit For
[instructions]
End If '<~ expecting "Next" before that "End If" token.
Running an auto-indenter would have made this problem obvious, I think. I happen to manage an open-source project that ported the popular Smart Indenter VBE add-in to .NET, so that it can run in 64-bit environments. See rubberduckvba.com for all the features.

If File = "False" Application.GetOpenFileName Error 13 Type Mismatch

I'm working on a code that uses the Application.GetOpenFileName. Im trying to ensure that that code doesn't break if someone hits cancel when selecting a file. I have a if statement that states if file = "false" then show a msgbox and exit sub. This works fine when no file is selected, however when I run the macro with the files selected then I get a Type Mismatch error. Ive tried a bunch of different runarounds and nothing has worked. Ive looked at other similar questions on here but nothing has worked for me.
Dim nom As String
Dim wb1, wb2, wb3, wb4, wb5 As Excel.Workbook
Dim i, j, k, file As Variant
nom = ActiveWorkbook.Name
If CurDir() <> CurDir("J:") Then
ChDrive "J:"
ChDir "J:FEA Material Data"
End If
For i = 1 To 5
Application.ScreenUpdating = False
MsgBox ("Select Compound" & vbNewLine & vbNewLine & "If Data From Criterion, Select Loading Only" & vbNewLine & vbNewLine & "If Data From Alliance, Select All")
file = Application.GetOpenFilename( _
FileFilter:="Text Files (*.csv), *.csv", _
MultiSelect:=True)
If file = "False" Then
MsgBox "No File Selected"
Exit Sub
Else
counter = 1
While counter <= UBound(file)
Workbooks.Open file(counter)
counter = counter + 1
Wend
End If
more code
When it has files it returns a variant with an array. Debug.Print VarType(file) returns 8204. So you need to check the array for file names. If the user selects Cancel then the Variant will be a boolean.
If VarType(file) = 11 Then
MsgBox "No File Selected"
Exit Sub
Or more readable (thanks to Dirk Reichel):
If Not IsArray(file) Then
MsgBox "No File Selected"
Exit Sub
Determining the Type of a Variant

Excel vba to solve vba error by "if error, then" rule

First of all, thanks for all the answers I have gotten on my previous questions, you really helped me out. The excel has evolved and now I'm ready to open different excel sheets in the background and print out different sheets on different printers. However, I'm working on a network that changes it's settings (which appear to change randomly).
Sub Client_Overzetten()
Application.ScreenUpdating = False
'
Workbooks.Open ("G:\Moe\WD\Planning&Control\Client.xlsm")
....etc...
However, if my colleague would try to open this file, he will get an error, as the same document has a different link (due to access restrictions).
His link is
G:\WD\Planning&Control\Client.xlsm")
Is there a formula to go to another location the moment it hits an error? Something like:
Sub Kids_II_Overzetten()
'
Application.ScreenUpdating = False
'
Workbooks.Open ("G:\Moe\WD\Planning&Control\Client.xlsm")
If error, then
Workbooks.Open ("G:\WD\Planning&Control\Client.xlsm")
I have the same problem with the serverports of the printer, these ports change randomly
ActivePrinter = "\\w8vvmprint01\Moecombi07 op Ne07:"
However, the next day it can be the same, or can be a different port
ActivePrinter = "\\w8vvmprint01\Moecombi07 op Ne03:"
With the solving of the problem of my first question, can I answer my second question as well (on error, go to the next line)?
Thanks in advance :)
For the network locations you'll need to use the UNC path which will not change rather than the mapped path which can change on different computers.
To find your UNC paths open a command prompt (Run - cmd.exe) and type in net use.
The resulting table will give the local and remote names of the drives- just replace your mapped (local) connection with the remote one.
For example,
G:\Moe\WD\Planning&Control\Client.xlsm
may become
\\MyServerName\Moe\WD\Planning&Control\Client.xlsm
Edit - the server name can also be found on the file explorer - windows key + E to open.
It will appear in the folder name as Moe on 'MyServerName' (G:)
To only use the mapped locations you could try:
Sub Test()
Dim wrkBk As Workbook
Dim sFileLocation As String
On Error GoTo ERROR_HANDLER
sFileLocation = "S:\Bartrup-CookD_SomeLocation\New Microsoft Excel Worksheet.xlsx"
Set wrkBk = Workbooks.Open(sFileLocation)
On Error GoTo 0
Exit Sub
ERROR_HANDLER:
Select Case Err.Number
Case 1004 'Microsoft Excel cannot access the file
sFileLocation = "S:\Bartrup-CookD\New Microsoft Excel Worksheet.xlsx"
Resume
Case Else
MsgBox "Error " & Err.Number & vbCr & _
" (" & Err.Description & ") in procedure Test."
Err.Clear
Application.EnableEvents = True
End Select
End Sub
or ask the user to select the correct file:
Public Sub AskForFile()
Dim vFile As Variant
Dim wrkBk As Workbook
vFile = GetFile("S:\Bartrup-CookD\")
If vFile <> "" Then
Set wrkBk = Workbooks.Open(vFile)
End If
End Sub
Public Function GetFile(Optional startFolder As Variant = -1) As Variant
Dim fle As FileDialog
Dim vItem As Variant
Set fle = Application.FileDialog(msoFileDialogFilePicker)
With fle
.Title = "Select a File"
.AllowMultiSelect = False
.Filters.Add "Excel Files", "*.xls*", 1
If startFolder = -1 Then
.InitialFileName = Application.DefaultFilePath
Else
If Right(startFolder, 1) <> "\" Then
.InitialFileName = startFolder & "\"
Else
.InitialFileName = startFolder
End If
End If
If .Show <> -1 Then GoTo NextCode
vItem = .SelectedItems(1)
End With
NextCode:
GetFile = vItem
Set fle = Nothing
End Function

How to open a file directory when only know part of the file name

Ok so I am trying to quickly open a file path using 2 cell values, everything works fine if I know the information verbatim. My issue is on the last value I will only have the first part of the file name, I have tried using the wildcard * but can't seem to get it to work. Keep getting "Path not found error". The second value is a project name, however, the folders also contain a description of the project. For example I know the project name is TB1756_2156 but the folder is named "TB1756_2156 Project Description Person in Charge January 2014" this is the code I have so far:
Sub Button2_Click()
ChDrive "S:\"
ChDir "S:\CLIENTS " & Range("B10").Value & "\Client1\" & Range("B11").Value & "*\Sample"
strFile = Application.GetOpenFilename
End Sub
EDIT:
Ok so if I where to manually open the file I want to examine this would be my path: S:\CLIENTS YEAR\FOLDER NAME\Project # Description Project Lead Year\Sample\File I want.xls
The vba I want open the dialog box and goes to the S:\CLIENTS then adds value from cell B10 then continues to FOLDER NAME\ then grabs just the Project # from cell B11 as this is all you would have handy , then would fill in the missing information, then continue to \Sample where the user would then select the file they want to open.
So manipulating the code provide by #dcromley this is what I got:
Sub UseFileDialogOpen()
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = True
.InitialFileName = "S:\CLIENTS " & Range("C10").Value & "\FOLDER NAME\ & Range("C11").Value
.Show
End With
End Sub
My issue with this is that it only enters the Project # into the File Name: but does not actually open it. So looking for a way to parse the directory as I have it already from my original code minus the "*\Sample" and that it would open the only folder that starts with the Project #
If you have the first part of the file name and want the filename, this will do it.
If you want a directoryname, change vbNormal to vbDirectory.
Sub Main()
MsgBox FindFilename("abc", "Z:\untitled\")
End Sub
Function FindFilename$(FirstPart$, DirWhere$)
Dim sw1&, Filename$
Do
If sw1 = 0 Then
sw1 = 1
Filename = Dir$(DirWhere, vbNormal)
Else
Filename = Dir$()
End If
If Filename = "" Then Exit Do
If FirstPart = Left$(Filename, Len(FirstPart)) Then
FindFilename = Filename
Exit Function
End If
Loop
MsgBox "Error - Filename not found"
End Function
EDIT:
From the Excel 2003 help (you have the complete (initial) dirname now, right?):
Sub UseFileDialogOpen()
Dim lngCount&
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = True
.InitialFileName = "Z:\untitled\"
.Show
For lngCount = 1 To .SelectedItems.Count
MsgBox .SelectedItems(lngCount)
Next lngCount
End With
End Sub
EDIT2: To open a *.xls file:
Sub Openxls()
Dim filename$
filename = "z:\untitled\dave1.xls"
Workbooks.Open filename
End Sub
I think dcromley's approach is sound but let us simplify things a little bit.
Dim prjDir As String, prjName As String
Dim initialFile As String, myDirString As String
'~~> B11 contains part of the foldername
'~~> B10 value as is
prjDir = "C:\CLIENTS\" & Range("B10") & "\Client1\" & Range("B11") & "*"
prjDir = Dir(prjDir, vbDirectory) '~~> use Dir to get the actual folder name
prjName = "C:\CLIENTS\" & Range("B10") & "\Client1\" & prjDir & "\*SAMPLE*.xls"
prjName = Dir(prjName, vbNormal) 'use Dir to get the actual filename
initialFile = "C:\CLIENTS\" & Range("B10") & "\Client1\" & prjDir & "\" & prjName
With Application.FileDialog(msoFileDialogFilePicker)
.Filters.Add "Excel Files", "*.xls"
.FilterIndex = 1
.InitialFileName = initialFile
.AllowMultiSelect = False
If .Show = False Then MsgBox "Please select Excel file.", vbExclamation: Exit Sub
myDirString = .SelectedItems(1)
.Filters.Clear
End With
Workbooks.Open myDirString '~~> Open the file
Is this close to what you want to achieve?
Btw, I assumed your Project # is unique.