Excel-VBA ListBox Item to String function - excel

I have a Userform which allows user to transfer item from ListBox1 to ListBox2.
The items in ListBox2 are supposed to be filenames of excel files which are to be imported.
I have an overall idea of how this can operate but I am stuck with the problem that I cannot open the file with the item name in ListBox2.
My question is, is it possible to "convert" the item name in a Listbox to a string so it can be used as the filename for file opening?
I tried to use the MsgBox to test if the Listbox2(i) / ListBox2.Name(i) / ListBox2.List(i) argument returns any values but unfortunately it doesn't. It always shows blank.
'This is the part where I try to open the files indicated in ListBox2
Dim directory = "my directory is here"
For i = 0 To ListBox2.ListCount - 1
Application.Workbooks.Open Filename:= directory & "\" & "FinalExcel.xlsx" 'This one is for testing to open file and it works.
Application.Workbooks.Open Filename:= directory & "\" & ListBox2(i)
Next

As mentioned in the comments, proper way to refer to ListBox items in an array-like fashion is via the ListBox.List(i) route.
Also a good practice would be to to check first whether the ListBox is empty, because attempting to open an empty file (because of non-existent ListBox field) will result in an error!
If Not ListBox2.ListCount = 0 Then
For i = 0 To ListBox2.ListCount - 1
Application.Workbooks.Open Filename:= directory & "\" & ListBox2.List(i)
Next i
End If

Related

DocumentExport copies pdf to an excel page but leaves a copy of the pdf open, which I cannot close

I have a Microsoft project vba application where I want to copy a selection of tasks using the "marked" field to identify all of the predecessor tasks to a target task, identified as the "target" below. When I have traced the network back to include only incompleted tasks, control passes to a routine which uses DocumentExport to create a copied file and save it to a pdf. Then, using ActiveSheet.OLEObjects.add, take this PDF and copy to a specific excel Tab with the "A3" cell being the top/left corner for the file to be placed.
excerpts of my current code:
target = ActiveCell.Task
SaveFilePath = "C:\Macros\"
SaveFileName = SaveFilePath & "Target-" & target & ".pdf"
SaveFilePath = "C:\Macros\"
SaveFileName = SaveFilePath & "Target-" & target & ".pdf"
Application.FilePageSetupView Name:=".MarkedPred_View", allsheetcolumns:=True, BestPageFitTimescale:=True
Application.FilePageSetupPage Name:=".MarkedPred_View", Portrait:=False, PagesTall:=6, PagesWide:=1, PaperSize:=pjPaperLegal, FirstPageNumber:=False
StrHeader = "&18&B" & GetFontFormatCode("Calibri") & "Status Date=" & Format(ActiveProject.StatusDate, "mm/dd/yy") & " Task Name= " & SelTask.Name & " ID:" & SelTask.ID & " UID:" & SelTask.UniqueID
Application.FilePageSetupHeader Name:=".MarkedPred_View", Alignment:=pjCenter, Text:=StrHeader
Application.FilePageSetupLegend Name:=".MarkedPred_View", LegendOn:=pjNoLegend
DocumentExport SaveFileName, pjPDF, FromDate:=EarliestStart - 30, ToDate:=LFin + 30
xlsheet.Range("A3").Select
ActiveSheet.OLEObjects.Add(FileName:=SaveFileName, Link:=True _
, DisplayAsIcon:=False).Activate
If I set the Link property to false, the copy to excel does not happen
sbDeleteAFile (SaveFileName)
Sub DeleteAFile(ByVal FileToDelete As String)
IsFileOpen (FileToDelete)
SetAttr FileToDelete, vbNormal
Kill FileToDelete
End Sub
Function IsFileOpen(FileName As String)
Dim filenum As Integer, errnum As Integer
OutputStr = ("1587 - IsFileOpen - started for = " & FileName) 'added
Call Txt_Append(MyFile, OutputStr)
On Error Resume Next ' Turn error checking off.
filenum = FreeFile() ' Get a free file number.
' Attempt to open the file and lock it.
Open FileName For Input Lock Read As #filenum
Close filenum ' Close the file.
errnum = Err ' Save the error number that occurred.
On Error GoTo 0 ' Turn error checking back on.
' Check to see which error occurred.
Select Case errnum
Case 0
IsFileOpen = False
'Open (Filename)
' Error number for "Permission Denied."
' File is already opened by another user.
OutputStr = ("1587 - IsFileOpen - is NOT Open") 'added
Call Txt_Append(MyFile, OutputStr)
Case 70
IsFileOpen = True
' Another error occurred.
Case Else
OutputStr = ("1587 - IsFileOpen - IS Open") 'added
Call Txt_Append(MyFile, OutputStr)
Error errnum
End Select
End Function
"LFin" is the finish date of the target task, from which I am collecting all of its predecessors. I am using the finish date as the "Latest Finish" (LFIN) to bound the "ToDate" in the command.
The error appears with the "ActiveSheet.OLEObjects.Add (fileName:=SaveFilename, Link:=True _" command, where the PDF is opened and copied to the specified excel tab with cell "A3" being the point of the paste for the image.
I do not have any code to close the PDF in this snippet so I get an error when I try to delete an open file. I have seen lots of discussion on various boards where if a file is opened by another application, MS Project VBA cannot delete it as it does not have the handle to the file (??). If I manually close the PDF, close the error notification in the debugger and then press "Run/Continue" , the PDF is deleted and cycles back through the main routine, just like I want it to but I have to again close the newly created PDF, clear the dialog and select Run/Continue.
The only section of this code which does not work as desired (and is currently missing in this code) is having the ability to close the PDF after it has been copied to Excel as it is no longer needed. I have only seen very complicated code which gets the handle of the PDF and then allows you to close the specific file without affecting any other PDF files which may also be open and are not part of this process.
Does anyone have any ideas? I first started using CopyToClipboard, but this command only can copy 16 rows of MS Project schedule to the clipboard. Then, I tried ExportAsFixedFormat, but the FromDate and ToDate entries have no effect on the displayed image.
Using DocumentExport and Application.OLEObjects.Add allows me to copy unlimted pages of schedule to the clipboard and paste into an excel tab showing the desired dates only.This is the closest I have been able to come to get what I want the output to look like. I have been unable to find an associated command to Application.OLEObjects.Add command which I can use to close the PDF file created by the Application.OLEObjects.Add. It certainly makes sense that you want to open the PDF file so it can be copied to the Excel tab, but it is surprising there is not also an easy way to close that PDF file after it has served its purpose.
The question boils down to this:
The error appears with the "ActiveSheet.OLEObjects.Add
(fileName:=SaveFilename, Link:=True, DisplayAsIcon:=False).Activate" command, where the PDF is
opened and copied to the specified excel tab...
The reason the pdf file opens is that the code is telling it to. By using the Activate method on the OLEObject just added, it activates it--meaning in opens the pdf file.
The solution is to simply the OLEObjects.Add method to this:
ActiveSheet.OLEObjects.Add FileName:=SaveFileName

Get value from closed Excel workbook via HTTP link

I have a bunch of Excel workbooks that are stored on a shared online directory (kind of like Dropbox) in different folders. I am creating a master workbook to pull values from these Excel workbooks into a summary. While testing I've managed to create one that works if the workbooks are stored in my disk drives and I refer to their directories, but not via the HTTP links they are stored on.
I'm currently using the ExecuteExcel4Macro macro to retrieve values from closed workbooks on my computer and passing the directory as the argument. Some code for example which works if it's a directory on the hard drive:
Private Function GetValue(path, file, sheet, ref)
' Retrieves a value from a closed workbook
Dim arg As String
' Make sure the file exists
If Right(path, 1) <> "\" Then path = path & "\"
If Dir(path & file) = "" Then
GetValue = "File Not Found"
Exit Function
End If
' Create the argument
arg = "'" & path & "[" & file & "]" & sheet & "'!" & _
Range(ref).Range("A1").Address(, , xlR1C1)
' Execute an XLM macro
GetValue = ExecuteExcel4Macro(arg)
End Function
Sub TestGetValue()
p = "c:\XLFiles\Budget"
f = "Budget.xls"
s = "Sheet1"
a = "A1"
MsgBox GetValue(p, f, s, a)
End Sub
Is there any way to get this to work with direct HTTP links to Excel workbooks instead of directories? Downloading them all into my computer isn't really an option, unless I could somehow change it to download each workbook automatically, get the value and then delete it, or something like that?

How to check if a range contains a word?

I have 3 Excel files that have in the column B the comments: ok or check. Column C contains the product numbers of the products that are either ok or need to be checked. I want to create a list (an overview) in another Excel file (4) of all the products that have the word "check" in column B in the other three Excel files (1,2,3).
I cannot use a pivot table in the three excels because it has to be refreshed manually.
Filter is also not an option. I would like to use VBA/Macros in Excel.
Excel 1
Status Product number
check 1254968
ok 5541485
check 2153654
ok 4588999
ok 8954668
ok 6945665
check 7469968
check 6665448
Excel 2
Status Product number
ok 7455561
ok 5145684
ok 4589666
check 4896471
check 1117347
check 5656478
ok 5256488
Excel 3
Status Product number
ok 3389741
check 6754889
check 1489798
ok 6489646
Excel 4
Products to check
1254968
2153654
7469968
6665448
4896471
1117347
5656478
6754889
1489798
I expect to have a list with all the product numbers that need to be checked in my 4th. Excel.
Create a new workbook in the same folder as the other files are located. Please consider to move away any other .xlsx files before running this macro :) If you need to run it in a specific folder and you are not able to move the files, please include a condition based on the name of the files that you do want to use. Otherwise, the below should be sufficient. Please read all comments in the code.
Sub test()
Dim wb1, wb2 As Workbook
Dim HeadSet As Boolean
Set wb1 = ThisWorkbook
FolderName = "your/path/" 'full path name to folder where xlsx is located
file_name = Dir(FolderName & "*" & ".xlsx", vbDirectory) 'assuming the files are all .xlsx
HeadSet = False 'for fun
'for each file in FolderName
Do While Right(file_name, 5) = ".xlsx" And file_name <> ""
'open workbook
Set wb2 = Workbooks.Open(file_name, False, True)
With wb2.Sheets(1)
For i = .Range("B1").End(xlDown).Row To .Range("B20000").End(xlUp).Row 'change .sheets(1) 1 = index to > your index, or "sheetname"
If LCase(Trim(.Range("B" & i).Value)) = "check" Then 'checks lowercase, so condition should be lower
'create headers in output sheet
If HeadSet = False Then
wb1.Sheets(1).Range("A1").Value = "Products"
wb1.Sheets(1).Range("A1").Value = "Result of check"
HeadSet = True
End If
'change wb1.sheets(index) to your index, or the sheet name between ""
wb1.Sheets(1).Range("A" & wb1.Sheets(1).Range("A20000").End(xlUp).Row + 1).Value = .Range("C" & i).Value
wb1.Sheets(1).Range("B" & wb1.Sheets(1).Range("A20000").End(xlUp).Row + 1).Value = .Range("B" & i).Value
End If
Next i 'next iteration
End With
wb2.Close False 'close workbook
file_name = Dir 'go to next file
Loop
End Sub

Automatically name a file based on cell data when saving a spreadsheet?

I have an .xltm template spreadsheet that I'm wondering if I can get a macro to populate the "save as" file name based on cell data, is this possible?
There are over 50 people who will have this spreadsheet, it's more of a form, and we are trying to figure out a way to keep the filenames uniform. I know there is the ThisWorkbook.BeforeSave, but I'm not really having any luck there. I just need it to make a file named something like $A$1 R $B$1 T $B$3.xlsx
Any ideas on how to do this?
Sure.
Sub SaveMyWorkbook()
Dim strPath As String
Dim strFolderPath as String
strFolderPath = "C:\"
strPath = strFolderPath & _
Sheet1.Range("A1").Value & "R" & _
Sheet1.Range("B1").Value & "T" & _
Sheet1.Range("B3").Value & ".xlsx"
ActiveWorkbook.SaveAs Filename:=strPath
End Sub
EDIT: After you clarified your question in your comment below, I can now safely say that the answer is: No, what you are asking is not possible.
What is possible is to put a big, fat command button on your sheet that says "Press me to save", and have that button call the above Sub. You can set a fixed folder, as in the example above, or have the user pick a folder using the FileDialog object (or the GetSaveAsFilename function, but then the user will be able to change the suggested filename, so less safe).

Simple VBA/Macro need to create a new text file with the contents of active sheet without changing filename

I need to export data in a sheet to a text file without changing the file name (i.e. not doing "save as". Also it would be great if the file name could look at the previous like file name in the folder and increase by 1 digit (i.e. :file_1.txt, file_2.txt, etc.)...
Thanks!!
If you want to avoid the current name of your excel file being changed, just save the current worksheet, not the whole workbook (the VBA equivalent of the SaveAs function is ActiveWorkbook.SaveAS, to save just the current sheet use ActiveSheet.SaveAS).
You can use the following macro:
Sub Macro1()
Application.DisplayAlerts = False
ActiveSheet.SaveAs Filename:="NewFile.txt", FileFormat:=xlTextWindows
Application.DisplayAlerts = True
End Sub
Toggling the DisplayAlerts property avoids a message box that is displayed if the given file already exists.
If want to save more than one sheet, you need to iterate through the Sheets collection of the ActiveWorkbook object and save each sheet to a separate file.
You can get a new file name as illustrated below, it includes a date. If you would like to add some details on what you want to export, you may get a fuller answer.
Function NewFileName(ExportPath)
Dim fs As Object '' or As FileSytemObject if a reference to
'' Windows Script Host is added, in which case
'' the late binding can be removed.
Dim a As Boolean
Dim i As Integer
Dim NewFileTemp As string
Set fs = CreateObject("Scripting.FileSystemObject")
NewFileTemp = "CSV" & Format(Date(),"yyyymmdd") & ".csv"
a = fs.FileExists(ExportPath & NewFileTemp)
i = 1
Do While a
NewFileTemp = "CSV" & Format(Date(),"yyyymmdd") & "_" & i & ".csv"
a = fs.FileExists(ExportPath & NewFileTemp)
i = i + 1
If i > 9 Then
'' Nine seems enough times per day to be
'' exporting a table
NewFileTemp = ""
MsgBox "Too many attempts"
Exit Do
End If
Loop
NewFileName = NewFileTemp
End Function

Resources