Keep VBA Function Value in Sub Routines - vba

I have a little problem which I don't know how to solve. I have 2 functions which allows my user to select a template file and a folder the goal is for me to keep the location of my template file and folder path in order to use it for a record set but only problem in the subroutines the values of those paths are pass as soon as I'm done selecting them so I can use them so this is my code
Function SaveExcelDialog() As String
Dim strSelectedFolder As String
Dim strGetFolder As String
'Choosing the location of the folder where i will save all my recordset
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Select a Folder" 'window title
.AllowMultiSelect = False 'avoiding multiple selection
.Show
strSelectedFolder = .SelectedItems.Item(1) 'taking the selected path folder
End With
GetFolder = strSelectedFolder 'returning the path of the folder
End Function
Public Function ChooseTemplateFile() As String
' my variables
Dim strSelectedTemplateFile As String
Dim strTemplatePath As String
'selecting a template file
With Application.FileDialog(msoFileDialogFilePicker)
.Title = "Select a Template File" 'window title
.AllowMultiSelect = False 'avoiding multiple selection
.Filters.Add "Classeur Excel", "*.xls; *.xlsx; *.xlsm" 'filter all the file that are allow to be choosen
.Show
'storing the path of my excel file
TemplateFile = .SelectedItems.Item(1) 'keeping the path
End With
strTemplatePath = strSelectedTemplateFile 'returning the path string value
End Function
Those two examples work but, the problem I encounter is in my sub routine. As soon as I call my function and the function has been executed the value of those two function are not kept and I can't use those variable later on when I need them .
Private Sub Run_Click()
'My Data Variables
Dim strCountry, strSelectedYear, strLink, strCountryLink, strDomain, strDomainLink, strDateLink, DOsSQL As String
Dim iSelectedYear As Integer
Dim strGetFolder, strTemplatePath As String
Dim i As Long
'Variables for query
Dim qdf As DAO.QueryDef
Dim qdfDOs As DAO.QueryDef
Dim rs As DAO.Recordset
Dim rsDOs As DAO.Recordset
strTemplatePath = ChooseTemplateFile() ' value are not kept they are erase as soon as i go to the next line
strGetFolder = SaveExcelDialog() ' value are not kept they are erase as soon as i go to the next line
'taking the value of the file and the folder picked
Dim db As DAO.Database
Dim arrReports(4, 3) As String
Dim strReportTitle As String....

The reason your values are disappearing is that you are assigning the result of the function to your variable, but you are not returning any result from your functions.
Instead, it looks like you're trying to assign values to the outer variables from inside the functions.
This could work with a few modifications, but it is more usual (and safer) to do the following:
Function SaveExcelDialog() As String
'Choosing the location of the folder where i will save all my recordset
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Select a Folder" 'window title
.AllowMultiSelect = False 'avoiding multiple selection
.Show
'To return a value from a function, assign it to the function's name.
SaveExcelDialog = .SelectedItems.Item(1)
End With
End Function
Public Function ChooseTemplateFile() As String
'selecting a template file
With Application.FileDialog(msoFileDialogFilePicker)
.Title = "Select a Template File" 'window title
.AllowMultiSelect = False 'avoiding multiple selection
.Filters.Add "Classeur Excel", "*.xls; *.xlsx; *.xlsm" 'filter all the file that are allow to be choosen
.Show
'Again, let's just assign the result to the name, in order to
'return the value.
ChooseTemplateFile = .SelectedItems.Item(1)
End With
End Function
If you like, you can write a test procedure to make sure your values get stored in the variables.
Public Sub TestFilePickers()
Dim strGetFolder, strTemplatePath As String
strTemplatePath = ChooseTemplateFile()
strGetFolder = SaveExcelDialog()
Debug.Print(strTemplatePath)
Debug.Print(strGetFolder)
End Sub

Related

Transfer Spreadsheet to Access Database with VBA

I have a browse button and pick and place the file name and path in textbox5. I need to use the same value in my file name but it does not work. It throws:
Run Time Error 2522- The action or method requires a File Name argument
Private Sub Command10_Click()
Dim dbs As DAO.Database
Dim td As DAO.TableDef
Dim fileName As String
'set current database
Set dbs = CurrentDb
Me.Text5 = fileName
DoCmd.TransferSpreadsheet acImport, , "tblS3DimportTemp", fileName, True
MsgBox "Data Uploaded!"
End Sub
Instead of: Me.Text5 = fileName
write:
fileName = Me.Text5
In many programming languages the left variable gets the value of the right one.

Excel VBA code For opening Excel xlsx File on a daily Basis with date in his name

I have 2 files that I want to merge to one report. Both files are in different folders and they are alone in their folder.
My problem is that when I dim each workbook as a variable I need to put a path with the name of the file.
I want that the path will stay and every time I run the Macro it will dim the current workbook in the file as "x"
Name of file for example - Clean room GSS parts - tracking file 17.05.2017
Here is my code:
Set x = Workbooks.Open("C:\Users\rosipov\Desktop\eliran\MFG - GSS\GSS\Clean room GSS parts - tracking file 17.05.2017.xlsx")
Thanks for helping.
You can convert the date of a cell, input or NOW to a string with the format you use in the filename:
FORMAT(NOW(),"dd.mm.yyyy")
Now you can use this when opening the file:
Set x = Workbooks.Open("C:\Users\rosipov\Desktop\eliran\MFG - GSS\GSS\Clean room GSS parts - tracking file " & FORMAT(NOW(),"dd.mm.yyyy") & ".xlsx")
Remember that you can use other values than the current date NOW().
You could perhaps, ask the user to select the file that you are wanting to select using the File Dialog Box.
Option Explicit
Public Enum FileDialogType
msoFileDialogOpen = 1
msoFileDialogSaveAs = 2
msoFileDialogFilePicker = 3
msoFileDialogFolderPicker = 4
End Enum
Public Function OpenTargetWBExample()
Dim FilePath As String: FilePath = FileDialog(msoFileDialogFilePicker, "Select workbook to open")
If Len(FilePath) = 0 Then Exit Function
Dim TargetWB As Workbook: Set TargetWB = Workbooks.Open(FilePath)
'Extra code goes here
Set TargetWB = Nothing
End Function
Public Function FileDialog(ByVal DialogType As FileDialogType, Optional ByVal DialogTitle As String, _
Optional MultiSelect As Boolean, Optional ByVal FileFilter As String) As String
'If MultiSelect then outputs files in the following format: "File1;File2;File3"
'Custom File Extension Filter Format: "File Description 1~File Extension Filter 1|File Description 2~File Extension Filter 2"
Dim FileDialogObject As FileDialog: Set FileDialogObject = Application.FileDialog(DialogType)
Dim Index As Long, Filters() As String, Element() As String
Dim SelectedFile As Variant
With FileDialogObject
If Len(DialogTitle) > 0 Then .Title = DialogTitle
.AllowMultiSelect = MultiSelect
If Len(FileFilter) > 0 Then
Filters = Split(FileFilter, "|")
For Index = 0 To UBound(Filters)
Element = Split(Filters(Index), "~")
.Filters.Add Element(0), Element(1), (.Filters.Count + 1)
Next Index
End If
.FilterIndex = 0
.Show
.Filters.Clear
For Each SelectedFile In .SelectedItems
FileDialog = FileDialog & CStr(SelectedFile) & ";"
Next SelectedFile
If Len(FileDialog) > 0 Then FileDialog = Left(FileDialog, Len(FileDialog) - 1)
End With
Set FileDialogObject = Nothing
End Function
since there is only one file in the directory
dim aaa as String
aaa = ""C:\Users\rosipov\Desktop\eliran\MFG - GSS\GSS\"
Set x = Workbooks.Open(aaa & Dir(aaa))

How do I call this subroutine from a button click on an Access form?

So, dumb question, but I can't figure it out. I have the following code that searches for a file path name and I believe adds the record to a table (untested). But, the problem is I am unable to Call this subroutine. I'd like to be able to click a button on a form and run. Does anyone know how I do this? thank you!
Public Function SelectFile() As String
Dim f As FileDialog
Set f = Application.FileDialog(msoFileDialogOpen)
With f
.AllowMultiSelect = False
.Title = "Please select file to attach"
If .Show = True Then
SelectFile = .SelectedItems(1)
Else
Exit Function
End If
End With
Set f = Nothing
End Function
Public Sub AddAttachment(ByRef rstCurrent As DAO.Recordset, ByVal strFieldName As String, ByVal strFilePath As String)
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
'Ask the user for the file
Dim filepath As String
filepath = SelectFile()
'Check that the user selected something
If Len(filepath) = 0 Then
Debug.Assert "No file selected!"
Exit Sub
End If
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("Table1")
''''change this
'Add a new row and an attachment
rst.AddNew
AddAttachment rst, "Files", filepath
rst.Update
'Close the recordset
rst.Close
Set rst = Nothing
Set dbs = Nothing
End Sub
You would add an event procedure to the button in question:
In Form Design mode, click on the button
In the Properties Sheet, select the builder [...] button of the On Click event
You will go to the VBA editor. Enter code like:
Private Sub cmdAddAttachment_Click()
AddAttachment Nothing, "", ""
End Sub
That said, your AddAttachment routine has an apparent infinite loop. The line:
AddAttachment rst, "Files", filepath
Doesn't seem to actually fill any field values. In fact, variables rstCurrent, strFieldName and strFilePath are not used in the code. You probably will need to debug this routine before it will work.

LibreOffice how to get filepicker multiple file selection data

In LibreOffice 4.2 I am trying to open the file picker and select multiple files (which I succeeded), and then to transfer the names (and path) of those files to a variable (or array, does not matter).
Although I can open the file picker and select multiple files, I can get the file name and path of only one file (the first one). And I couldn't find any way to get the others.
I am using the following code:
Sub TakeFile()
Dim FileNames(0 to 100) as String
FileNames() = fImportLocalFile()
Msgbox FileNames
End Sub
Function fImportLocalFile() 'as String
' FJCC: Can't define the function as returning a String because now it returns an array
'this function opens a system file open dialog box and allows the
' user to pick a file from thier computer to open into the
' document for processing
'stores the filedialog object
Dim oFileDialog as Object
'stores the returned result of the activation of the dialog box
Dim iAccept as Integer
'stores the returned file name/path from the file dialog box
Dim sPath as String
'stores the set default path for the dialog box
Dim InitPath as String
'stores the types of files allowed in the filedialog
Dim sFilterNames as String
'setup the filters for the types of files to allow in the dialog
sFilterNames = "*.csv; *.txt; *.odt; *.ods; *.xls; *.xlt; *.xlsx"
'create the dialog box as a Windows File Dialog
oFileDialog = CreateUnoService("com.sun.star.ui.dialogs.FilePicker")
'set the filters for the dialog
oFileDialog.AppendFilter("Supported files", sFilterNames)
'set the path as blank
InitPath = ""
'add the default path to the dialog
oFileDialog.setDisplayDirectory(InitPath)
'setup the dialog to allow multiple files to be selected
oFileDialog.setMultiSelectionMode(True)
'set iAccept as the execution of the dialog
iAccept = oFileDialog.Execute()
'execute and test if dialog works
If iAccept = 1 Then
'set sPath as the chosen file from the dialog
'sPath = oFileDialog.Files(0)
FileArray = oFileDialog.getFiles() 'added by FJCC
'set the function as sPath for returning to the previous sub
fImportLocalFile = FileArray 'modified by FJCC
'end current if statement
End If
End Function
Your error is you are assigning the array of selected files to the funtion name itself! Choose a different name.
This works with me on LO 5.0.0.5
SUB TakeFile()
' Dim FileNames(0 to 100) as String
' Dont limit yourself!
FileNames = fImportLocalFile()
path = FileNames(0)
FOR i = 1 TO Ubound(FileNames)
print path + FileNames(i)
Next
End Sub
and within the function:
path = FileArray(0)
FOR i = 1 TO Ubound(FileArray)
print path + FileArray(i)
Next
fImportLocalFile = FileArray
There is a Interface XFilePicker2 which "extends file picker interface to workaround some design problems." This Interface has a Method getSelectedFiles.
See https://www.openoffice.org/api/docs/common/ref/com/sun/star/ui/dialogs/XFilePicker2.html.
Use this Method instead of XFilePicker.getFiles.
The following should work:
Sub TakeFile()
Dim FileNames() as String
FileNames = fImportLocalFile()
Msgbox Join(FileNames, Chr(10))
End Sub
Function fImportLocalFile() as Variant
Dim oFileDialog as Object
Dim iAccept as Integer
Dim sPath as String
Dim InitPath as String
Dim sFilterNames as String
sFilterNames = "*.csv; *.txt; *.odt; *.ods; *.xls; *.xlt; *.xlsx"
oFileDialog = CreateUnoService("com.sun.star.ui.dialogs.FilePicker")
oFileDialog.AppendFilter("Supported files", sFilterNames)
InitPath = ""
oFileDialog.setDisplayDirectory(InitPath)
oFileDialog.setMultiSelectionMode(True)
iAccept = oFileDialog.Execute()
If iAccept = 1 Then
fImportLocalFile = oFileDialog.getSelectedFiles()
Else
fImportLocalFile = Array()
End If
End Function

using Application.FileDialog to rename a file in VBA

Using VBA. My script moves a file into a directory. If that filename already exists in the target directory, I want the user to be prompted to rename the source file (the one that's being moved) before the move is executed.
Because I want the user to know what other files are in the directory already (so they don't choose the name of another file that's already there), my idea is to open a FileDialog box listing the contents of the directory, so that the user can use the FileDialog box's native renaming capability. Then I'll loop that FileDialog until the source file and target file names are no longer the same.
Here's some sample code:
Sub testMoveFile()
Dim fso As FileSystemObject
Dim file1 As File
Dim file2 As File
Dim dialog As FileDialog
Set fso = New FileSystemObject
fso.CreateFolder "c:\dir1"
fso.CreateFolder "c:\dir2"
fso.CreateTextFile "c:\dir1\test.txt"
fso.CreateTextFile "c:\dir2\test.txt"
Set file1 = fso.GetFile("c:\dir1\test.txt")
Set file2 = fso.GetFile("c:\dir2\test.txt")
Set dialog = Application.FileDialog(msoFileDialogOpen)
While file1.Name = file2.Name
dialog.InitialFileName = fso.GetParentFolderName(file2.Path)
If dialog.Show = 0 Then
Exit Sub
End If
Wend
file1.Move "c:\dir2\" & file1.Name
End Sub
But when I rename file2 and click 'OK', I get an error:
Run-time error '53': File not found
and then going into the debugger shows that the value of file2.name is <File not found>.
I'm not sure what's happening here--is the object reference being lost once the file's renamed? Is there an easier way to let the user rename from a dialog that shows all files in the target directory? I'd also like to provide a default new name for the file, but I can't see how I'd do that using this method.
edit: at this point I'm looking into making a UserForm with a listbox that gets populated w/ the relevant filenames, and an input box with a default value for entering the new name. Still not sure how to hold onto the object reference once the file gets renamed, though.
Here's a sample of using Application.FileDialog to return a filename that the user selected. Maybe it will help, as it demonstrates getting the value the user provided.
EDIT: Modified to be a "Save As" dialog instead of "File Open" dialog.
Sub TestFileDialog()
Dim Dlg As FileDialog
Set Dlg = Application.FileDialog(msoFileDialogSaveAs)
Dlg.InitialFileName = "D:\Temp\Testing.txt" ' Set suggested name for user
' This could be your "File2"
If Dlg.Show = -1 Then
Dim s As String
s = Dlg.SelectedItems.Item(1) ` Note that this is for single-selections!
Else
s = "No selection"
End If
MsgBox s
End Sub
Edit two: Based on comments, I cobbled together a sample that appears to do exactly what you want. You'll need to modify the variable assignments, of course, unless you're wanting to copy the same file from "D:\Temp" to "D:\Temp\Backup" over and over. :)
Sub TestFileMove()
Dim fso As FileSystemObject
Dim SourceFolder As String
Dim DestFolder As String
Dim SourceFile As String
Dim DestFile As String
Set fso = New FileSystemObject
SourceFolder = "D:\Temp\"
DestFolder = "D:\Temp\Backup\"
SourceFile = "test.txt"
Set InFile = fso.GetFile(SourceFolder & SourceFile)
DestFile = DestFolder & SourceFile
If fso.FileExists(DestFile) Then
Dim Dlg As FileDialog
Set Dlg = Application.FileDialog(msoFileDialogSaveAs)
Dlg.InitialFileName = DestFile
Do While True
If Dlg.Show = 0 Then
Exit Sub
End If
DestFile = Dlg.Item
If Not fso.FileExists(DestFile) Then
Exit Do
End If
Loop
End If
InFile.Move DestFile
End Sub
Here's some really quick code that I knocked up but basically looks at it from a different angle. You could put a combobox on a userform and get it to list the items as the user types. Not pretty, but it's a start for you to make more robust. I have hardcoded the directory c:\ here, but this could come from a text box
Private Sub ComboBox1_KeyUp(ByVal KeyCode As MSForms.ReturnInteger,
ByVal Shift As Integer)
Dim varListing() As Variant
Dim strFilename As String
Dim strFilePart As String
Dim intFiles As Integer
ComboBox1.MatchEntry = fmMatchEntryNone
strFilePart = ComboBox1.Value
strFilename = Dir("C:\" & strFilePart & "*.*", vbDirectory)
Do While strFilename <> ""
intFiles = intFiles + 1
ReDim Preserve varListing(1 To intFiles)
varListing(intFiles) = strFilename
strFilename = Dir()
Loop
On Error Resume Next
ComboBox1.List() = varListing
On Error GoTo 0
ComboBox1.DropDown
End Sub
Hope this helps. On error resume next is not the best thing to do but in this example stops it erroring if the variant has no files