How to filter file extensions - vb.net

I'm trying to separate files in a folder by extension, using the code below:
Dim file_list3 As String() = Directory.GetFiles(path, "*.xls")
Dim file_list4 As String() = Directory.GetFiles(path, "*.xlsm")
but all of the ".xls" files end up in list 4 along with the ".xlsm" files. How can I keep the subset of just ".xls" flies out of the list of ".xlsm" files?
Thanks.

I found the answer:
Dim file_list3 = Directory.GetFiles(path, "*.xls").Where(Function(item) item.ToLower().EndsWith(".xls"))
Dim file_list4 = Directory.GetFiles(path, "*.xlsm").Where(Function(item) item.ToLower().EndsWith(".xlsm"))
Thanks.

I finally managed to reproduce the behavior documented.
It seems that I have set this command on my working pc
fsutil 8dot3name set 0
this command disables the creation of the old 8.3 short filenames required at MS-DOS time.
With this configuration the command Directory.GetFiles(path, "*.xls") returns only the files that have exactly the extension specified and not other extensions that starts with XLS.
Applying the command
fsutil 8dot3name set 1
I expected to have the same result explained by the OP, but this is not the case with files already in the folder because they were created when the 8dot3name flag was disabled.
But a new file named test.xlsm started to appear between the files returned by the search pattern *.xls
So, to fix your problem you could use the fsutil command as explained in the article How to disable 8.3 file name creation on NTFS partitions and perhaps strip away the old 8.3 entries with the strip option or just use a slight variation of your code above
Dim all_files = Directory.EnumerateFiles(path, "*.xls")
Dim file_list3 = all_files.Where(Function(x) Path.GetExtension(x).ToLower = ".xls").ToList()
Dim file_list4 = all_files.Where(Function(x) Path.GetExtension(x).ToLower = ".xlsm").ToList()

Related

Merge pdf files with VBA and Foxit

I use Foxit Phantompdf, the complete version and ACCESS.
In our program, we have to save multiple pdf files, some of them should be merged in single files when saved.
Here is the code I use;
Dim phApp As PhantomPDF.Application
Dim n1 As String
Dim n2 As String
n1 = "c:\Temp\F3769-190136-GROUPE OCÉAN.pdf"
n2 = "c:\Temp\f3769-190136-GROUPE OCÉAN- facture.pdf"
Set phApp = CreateObject("PhantomPDF.Application")
Dim phCreator As PhantomPDF.Creator
Set phCreator = phApp.Creator
***'Call phCreator.CombineFiles("c:\Temp\F3769-190136-GROUPE OCÉAN.pdf|c:\Temp\f3769-190136-GROUPE OCÉAN- facture.pdf", "c:\Temp\F3769-190136-GROUPE OCÉAN.pdf", COMBINE_ADD_CONTENTS)***
Call phCreator.CombineFiles("""c:\Temp\" & n1 & "|'" & n2 & """" & ", " & """c:\Temp\F3769-190136-GROUPE OCÉAN.pdf"""" &", COMBINE_ADD_CONTENTS)
phApp.Exit
When I try it with the complete files names (in bold) the code works perfectly.
However, when I try to use variables, I get a
"Argument not optional"
error.
Can somebody help me ?
Thanks
Your string definitions in call line is incorrect.
You have defined n1 and n2 with the c:\temp already, and in your string conversion you add this again. I do not know if this is the route cause to your issue.
Furthermore I do not know the actual needed syntax for this phcreator.combine()
But is it not possible using only:
call pHcreator.combine(n1 & "|" & n2, …
The 'Argument not option' might imply you should add another input to your pHcreator, I would guess it could have something to do with FOXIT's combine function page settings. Try adding a input variable integer at the end of the function maybe?
But the fact that it works when writing strings in clear text would maybe suggest that the string manipulations is not correct?
I'm not a vba professional, but interested in the outcome, working myself with Foxit and also want to combine with vba. I'm currently not using version 9 som I seem to be out of luck, and only upgrading it I know what I want to do is possible.
I tried it, but got the same error message. So I took advantage of the fact that the function works when the file names are in plain text. I copied the files to be merged in a temporary folder and rename them. The renamed files are the then used in the merge function. It works perfectly, but Foxit adds a table of content page, and I don't know, yet, how to remove it. Here is my solution:
Private Sub Command4_Click()
Dim addi As String 'file to be merged to main file
Dim princi As String 'main file
Dim phApp As PhantomPDF.Application
'A temporary folder, in this case c:\t2, should be present
'In this example c:\Temp is the working folder
addi = "c:\Temp\filetomerge.pdf" 'full path of file to be merged
princi = "c:\Temp\mainfile.pdf" 'full path of main file
'fadd,pdf and fmain.pdf are the temporay files used in Foxit's function
FileCopy addi, "c:\t2\fadd.pdf" 'temporary file to be merged in temporary folder
FileCopy princi, "c:\t2\fmain.pdf" 'temporary main file in temporary folder
'Merge action
Set phApp = CreateObject("PhantomPDF.Application")
Dim phCreator As PhantomPDF.Creator
Set phCreator = phApp.Creator
Call phCreator.CombineFiles("c:\t2\fmain.pdf|c:\t2\fadd.pdf", "c:\t2\fmain.pdf", COMBINE_ADD_CONTENTS)
phApp.Exit
'Save merged file in working folder under main file name
Kill princi
FileCopy "c:\t2\fmain.pdf", princi
'delete temporary files
Kill "c:\t2\fadd.pdf"
Kill "c:\t2\fmain.pdf"
End Sub

Identify some files in Specialized.StringCollection

I read the *.fileExt files using:
Dim tempList As New Specialized.StringCollection
         tempList.AddRange(My.Computer.FileSystem.GetFiles(path, subFolders, "*" & fileExt).ToArray)
When processing I find some files that were deleted and are invisible from the file explorer but that are read by .GetFiles, they have their original name preceded by: "~$"
Example: "C:.......\~$OriginalFileName.fileExt"
I tried to exclude files that have "~$" at the beginning of the name, but it's not a good solution since I can create and save a file with "~$" at the beginning of the name, then the code would avoid a file that was never deleted.
I want to continue using .AddRange and exclude deleted files, I see two options:
Prevent .GetFiles from taking those files.
Identify them in tempList to avoid processing them.
I can't get any of the two to work.
I guess there is a simple way to identify if a file is deleted or not... an attribute or flag that identifies it as "deleted"... but I don't know how to do it. It's possible? How I should proceed?
Some programs create a backup file while a file is being edited, and those files are named starting with "~$" and have the hidden attribute set. Sometimes those files get orphaned, perhaps because of a program crash, but you don't notice them because they are hidden.
To avoid getting hidden files, you can select only files which do not have the hidden attribute, something like this:
Option Strict On
Option Infer On
Imports System.IO
Module Module1
Sub Main()
Dim srcDir = "C:\temp\testfiles"
Dim fileExt = ".txt"
Dim tempList As New Specialized.StringCollection()
Dim selectedFiles = (New DirectoryInfo(srcDir)).GetFileSystemInfos("*" & fileExt).
Where(Function(fi) Not (fi.Attributes And FileAttributes.Hidden) = FileAttributes.Hidden).
Select(Function(fi) fi.FullName)
tempList.AddRange(selectedFiles.ToArray())
For Each s In tempList
Console.WriteLine(s)
Next
Console.ReadLine()
End Sub
End Module
I created some files in a directory, and one of them I named starting with "~$" and set its hidden attribute:
C:\temp\testfiles>dir
Directory of C:\temp\testfiles
21/10/2019 15:48 0 one.txt
21/10/2019 15:49 0 two.txt
21/10/2019 15:48 0 ~$one.txt
3 File(s) 0 bytes
C:\temp\testfiles>dir /a:h
Directory of C:\temp\testfiles
21/10/2019 15:49 0 ~$three.txt
1 File(s) 0 bytes
and got this output from the program:
C:\temp\testfiles\one.txt
C:\temp\testfiles\two.txt
C:\temp\testfiles\~$one.txt
N.B. You are probably making things difficult for yourself by using a Specialized.StringCollection() instead of a List(Of String).
This can help you:
tempList As New Specialized.StringCollection
tempList.AddRange((From sFile As String In My.Computer.FileSystem.GetFiles(path, subFolders, "*" & fileExt).ToList.AsEnumerable
Where sFile IsNot Nothing
Where sFile.IndexOf("~$") = -1).ToArray)

Directory.GetDirectories not returning subdirectories

I am trying to get all the sub-directories under C:\Program Files (x86)\Java\
Which should be jre1.8.0_25 for my computer, could have more if different versions are installed that's good, i want that.
But all i ever get is java from this code
Directory.GetDirectories("C:\Program Files (x86)\Java\", SearchOption.AllDirectories))
or
New System.IO.DirectoryInfo("C:\Program Files (x86)\Java").Name)
Where am i going wrong?
The goal is the insert that output from the above code into a database. I used to read it from the registry but Java8 doesn't work for my old code anymore.
First, this overload does not exist: GetDirectories(string, options)
There is:
GetDirectories(path as string)
GetDirectories(path as string, pattern as string)
GetDirectories(path as string, pattern as string, options As SearchOptions)
None of those match the way you are using it.
Second, you should not assume the name of system folders such as "C:\Program Files (x86)" - a German or French computer will not have such a folder.
This returns 75 folders on my machine:
' get program files
Dim fpath As String = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)
' append java
fpath = Path.Combine(fpath, "Java")
' fetch
Dim folders = Directory.GetDirectories(fpath, "*", SearchOption.AllDirectories)
Try this instead:
? = New System.IO.DirectoryInfo("C:\Program Files (x86)\Java").GetDirectories(SearchOption.AllDirectories)

Kill Command Deleting Wrong File(s)i

In Access VBA, I have a procedure I've put together to do this:
Allow the user to select zip file(s)
Extract any files from the zip files to the same directory (In this
specific use-case instance, it is ALWAYS extracting Excel files from
Zip files, never any change, and always using the same password)
Then I want the code to Delete the Zip file after extracting the
.xls file.
Everything works beautifully except the delete file portion. The issue is that when I tell it to delete "FileName.Zip", it is deleting "FileName.Zip" AND "FileName.xls"
Is there any way to make sure that he kill command ONLY deletes what I want it to delete? I've used it before on various occasions, and never had this happen before.
Here is the code I am using:
Dim fd As FileDialog
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim i As Variant
Set db = CurrentDb
Set rs = db.OpenRecordset("tblProjectPath")
Set fd = FileDialog(msoFileDialogFilePicker)
fd.AllowMultiSelect = True
fd.Title = "Select TOC Return File(s) to process"
fd.InitialFileName = rs.Fields("ProjectPath") & "\FilingReports\*.zip"
fd.Show
For Each i In fd.SelectedItems
'Debug.Print i
Debug.Print '------------------------'
Debug.Print i
Unzip (i) 'The bit calling the command line unzip utility to unzip the file - just telling it to extract all files to the current folder.
Debug.Print i
'Kill i
'had to take out the kill bit, b/c it was deleting both the .zip and .xls files which is not desired nor expected
If InStr(i, ".zip") Then
Kill i 'Tried to specify only .zip files even though think I shouldn't need to, but it's still deleting .xls files
End If
Next i
Edit: Add Unzip code to post:
Unzip code:
Sub Unzip(Path As String)
Dim strUnzip As String
Dim QU As String 'quotation mark
QU = Chr(34)
strUnzip = QU & "c:\program files (x86)\winzip\wzunzip" & QU & " -s" & _
"ZipPassword " & _
Path & " " '& _
Call Shell(strUnzip)
End Sub
At this point, I don't really think a "real" answer will come about. However, I'll post what I've decided to do with the particular process I'm writing this code for anyway.
I'm going to use a folder structure to divide up the files:
1. Place zip file(s)
2. Unzip files to a 2nd folder
3. After processing Excel files in 2nd folder, move to a 3rd "complete" folder.
This will get around the deleting wrong files bit.
Also, it appears that the cause for the issue is related to something to do with the call to the WinZip Command Line Unzip utility (wzunzip) in the Unzip code above, or else something with the tool itself. I thought that maybe it was b/c the tool was asking me if I wanted to overwrite existing files, but that wasn't the case, b/c I had the same issue when there were no files to overwrite.
Anyway, I'm attempting to close this one up at this point. Thanks to Wayne G. Dunn for his assistance on this.

Visual Basic: File is said to be in the wrong folder

Ok, here is my story:
I am building a fileviewer, and i am trying to delete the selected file in the listview.
when i try to delete it, it gave me an error saying the file wasnt found. I looked at my desktop and the file was there. here is the original code:
dim f as string = lv1.focuseditem.text
my.computer.filesystem.deletfile(f)
lv1.update()
this gave me that error. My updated code is supposed to show me where the computer thinks my file is:
Dim file As String = lv1.FocusedItem.Text
Dim testFile As System.IO.FileInfo
testFile = My.Computer.FileSystem.GetFileInfo(file)
Dim folderPath As String = testFile.DirectoryName
MsgBox(folderPath)
this shows a messagebox that shows the path of:
C:\Users\tgs266\Desktop\SIOS\SIOS\SIOS\obj\Debug\test.txt
but the real file location is:
C:\Users\tgs266\Desktop\test.txt
please help
How are you getting the filenames for the ListView? Is it just the filename and no path?
If, for example, lv1.FocusedItem.Text is "test.txt", and that is the value you use (without the path), by default the program will look in the directory it's executing in. This is most likely why you're seeing C:\Users\tgs266\Desktop\SIOS\SIOS\SIOS\obj\Debug\test.txt as the location, instead of what you expected.
If all the files are on your desktop, you can use Environment.GetFolderPath in conjunction with the Environment.SpecialFolder Enumeration to get the file, like this:
Dim file As String = lv1.FocusedItem.Text
Dim testFile As System.IO.FileInfo
testFile = My.Computer.FileSystem.GetFileInfo(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\" + file)
Dim folderPath As String = testFile.DirectoryName
MsgBox(folderPath)
However, if you're going to have files scattered throughout your system, you'd be better off storing the full path as #Plutonix indicates in his comment.
It looks like your code is looking in your applications path on the server while you want to look at the users desktop location.