On Error Resume Next
Set FileSysObj = CreateObject("Scripting.FileSystemObject")
Const ForReading = 1 ' Declare constant for reading for more clarity
Dim cntFile, strCSVFullFile, strCSVFile, strDIR, cntBadLines, cntAllLines, strArchiveDir, strSafeTime,strSafeDate
' -------------------------------------------------------------------------------------------
' Specify CSV file name from the input argument
strCSVFile = Wscript.Arguments(1) ' Transactions
strDIR = Wscript.Arguments(2) & "\" ' C:\Temp
strArchiveDir = Wscript.Arguments(3) & "\"
strSafeTime = Right("0" & Hour(Now), 2) & Right("0" & Minute(Now), 2) & Right("0" & Second(Now), 2)
strSafeDate = Year(Date) & Month(Date) & day(Date)
set folder = FileSysObj.getFolder(strDIR)
cntFile = 0
cntBadLines = 0
cntAllLines = 0
for each file in folder.Files
' check if the file is there and echo it.
if InStr(1,file.name,strCSVFile,1) <> 0 then
strCSVFullFile = file.name
cntFile = cntFile + 1
end if
next
if cntFile > 1 or cntFile = 0 then
' error and end
Wscript.Echo "Error - only 1 file required for this process. There are " & cntFile & " file(s) in the directory"
WScript.Quit
end if
wscript.echo "Checking the file " & strCSVFullFile & " in " & strDIR
NoOfCols = Wscript.Arguments(0) ' usually 8
strTemp = "temp.csv"
strmissing = "missingdata.csv"
Set objOutFile = FileSysObj.CreateTextFile(strDIR & strTemp,True)
Set objOutFileM = FileSysObj.CreateTextFile(strDIR & strmissing,True)
Set inputFile = FileSysObj.OpenTextFile(strDIR & strCSVFullFile, ForReading, True)
' Set inputFile as file to be read from
Dim row, column, outline
Dim fields '(7) '8 fields per line
inputFile.ReadAll 'read to end of file
outline = ""
ReDim MyArray(inputFile.Line-2,NoOfCols) 'current line, minus one for header, and minus one for starting at zero
inputFile.close 'close file so that MyArray can be filled with data starting at the top
Set inputFile = FileSysObj.OpenTextFile(strDIR & strCSVFullFile, ForReading, True) 'back at top
strheadLine = inputFile.ReadLine 'skip header , but keep it for the output file
objOutFile.Write(strheadLine & vbCrLf)
anyBadlines = False
badlineflag = False
Do Until inputFile.AtEndOfStream
fullLine = inputFile.Readline
fields = Split(fullLine,",") 'store line in temp array
For column = 0 To NoOfCols-1 'iterate through the fields of the temp array
myArray(row,column) = fields(column) 'store each field in the 2D array with the given coordinates
'Wscript.Echo myArray(row,column)
if myArray(row,0) = " " or myArray(row,1) = " " then
badlineflag = True
'missline = myArray(row,0) & ", " & myArray(row,1) & ", " & myArray(row,2) & ", " & myArray(row,3) & ", " & myArray(row,4) & ", " & myArray(row,5) & ", " & myArray(row,6) & ", " & myArray(row,7)
'Wscript.Echo missline
'Exit For
end if
if column = NoOfCols-1 then
outline = outline & myArray(row,column) & vbCrLf
else
outline = outline & myArray(row,column) & ","
'csvFile = Regex.Replace(csvFile, "(,\s*?"".*?)(,)(\s+.*?""\s*?,)", "$1$3") 'TEST
end if
Next
cntAllLines = cntAllLines + 1
' Wscript.Echo outline
if badlineflag = False then
objOutFile.Write(fullLine & vbCrLf)
else
' write it somewhere else, drop a header in the first time
if anyBadlines = False Then
objOutFileM.Write(strheadLine & vbCrLf)
End if
objOutFileM.Write(outline)
cntBadLines = cntBadLines + 1
badlineflag = False
anyBadlines = True
end if
outline = ""
row = row + 1 'next line
Loop
objOutFile.Close
objOutFileM.Close
inputFile.close
Wscript.Echo "Total lines in the transaction file = " & cntAllLines
Wscript.Echo "Total bad lines in the file = " & cntBadLines
The below line is able to work as it contains 7 commas (8 columns).
URXW_99,BYQ0JC6,2603834418,2017-10-30,Test,4.962644,2278.0000,ABC
The below line will throw an error as a result of more commas than 7 in the script.
URXW_99,BYQ0JC6,2603834418,2017-10-30,Test,4.962644,2278.0000,Redburn, Europe. Limited
If greater than 7 commas in the CSV file line, the aim is to wrap it all greater than 7 into one field.
E.g. how do you replace Redburn, Europe. Limited string with double quotes as it is one name.
For example, in a text file it would appear like below:
URXW_99,BYQ0JC6,2603834418,2017-10-30,Test,4.962644,2278.0000,"Redburn, Europe. Limited"
Is there a way to write a VB or VBA script to do the above and save it as a .csv file (which is opened via notepad to check the double quotes)?
Option Explicit
Option Compare Text
Public Sub ConvertFile()
Dim lngRowNumber As Long
Dim strLineFromFile As String
Dim strSourceFile As String
Dim strDestinationFile As String
strSourceFile = "U:\Book3.csv"
strDestinationFile = "U:\Book4.csv"
Open strSourceFile For Input As #1
Open strDestinationFile For Output As #2
lngRowNumber = 0
Do Until EOF(1)
Line Input #1, strLineFromFile
strLineFromFile = Right(Replace(strLineFromFile, ",", " ", 1), 1000)
Write #2, strLineFromFile
strLineFromFile = vbNullString
Loop
Close #1
Close #2
End Sub
As I see, you use MS Access (due to Option Compare Text line), so there is better built-in instruments for this task.
Use DoCmd.TransferText for it.
1st step is to create output specification via:
Here you can setup delimiters, even that differs from ", and handle other options.
After that you can use your set-up specification via following command
DoCmd.TransferText acExportDelim, "TblCustomers_export_spec", "TblCustomers", "C:\test\1.txt", True
In this case all characters escaping would be done through built-in instruments. It seems to be more easier to correct this code further.
As mentioned, there is VBScript workaround. For given input data, following function will do desired actions for given string:
Option Explicit
Function funAddLastQuotes( _
strInput _
)
Dim arrInput
arrInput = Split(strInput, ",")
Dim intArrSize
intArrSize = UBound(arrInput)
Dim intCurrentElement
Dim strOutput
Dim intPreLastElement
intPreLastElement = 6
For intCurrentElement = 1 To intPreLastElement
strOutput = strOutput & "," & arrInput(intCurrentElement)
Next
Dim strOutputLastField
For intCurrentElement = intPreLastElement + 1 To intArrSize
strOutputLastField = strOutputLastField & "," & arrInput(intCurrentElement)
Next
strOutputLastField = Right(strOutputLastField, Len(strOutputLastField) - 1)
strOutput = Right(strOutput, Len(strOutput) - 1)
strOutput = strOutput & "," & """" & strOutputLastField & """"
funAddLastQuotes = strOutput
End Function
MsgBox funAddLastQuotes("RXW_99,BYQ0JC6,2603834418,2017-10-30,Test,4.962644,2278.0000,Redburn, Europe,,, Limited")
Finally, here is working VBScript solution.
Option Explicit
Const ColumnsBeforeCommadColumn = 6
Function funAddLastQuotes( _
strInput _
)
Dim arrInput
arrInput = Split(strInput, ",")
Dim intArrSize
intArrSize = UBound(arrInput)
Dim intCurrentElement
Dim strOutput
Dim intPreLastElement
intPreLastElement = ColumnsBeforeCommadColumn
For intCurrentElement = 1 To intPreLastElement
strOutput = strOutput & "," & arrInput(intCurrentElement)
Next
Dim strOutputLastField
If (intPreLastElement + 1) < intArrSize _
Then
For intCurrentElement = intPreLastElement + 1 To intArrSize
strOutputLastField = strOutputLastField & "," & arrInput(intCurrentElement)
Next
Else
strOutputLastField = strOutputLastField & "," & arrInput(intArrSize)
End If
strOutputLastField = Right(strOutputLastField, Len(strOutputLastField) - 1)
strOutput = Right(strOutput, Len(strOutput) - 1)
strOutput = strOutput & "," & """" & strOutputLastField & """"
funAddLastQuotes = strOutput
End Function
Public Sub ConvertFile( _
strSourceFile _
)
Dim objFS
Dim strFile
Dim strTemp
Dim ts
Dim objOutFile
Dim objFile
Set objFS = CreateObject("Scripting.FileSystemObject")
Dim strLine
Dim strOutput
Dim strRow
strFile = strSourceFile
strTemp = strSourceFile & ".tmp"
Set objFile = objFS.GetFile(strFile)
Set objOutFile = objFS.CreateTextFile(strTemp,True)
Set ts = objFile.OpenAsTextStream(1,-2)
Do Until ts.AtEndOfStream
strLine = ts.ReadLine
objOutFile.WriteLine funAddLastQuotes(strLine)
Loop
objOutFile.Close
ts.Close
objFS.DeleteFile(strFile)
objFS.MoveFile strTemp,strFile
End Sub
ConvertFile "C:\!accsoft\_in.csv"
You should change following part: ConvertFile "C:\!accsoft\_in.csv as path to your file.
And ColumnsBeforeCommadColumn = 6 is the setting, at which column the chaos with commas begins
so I was wondering if i could get some help here. so basically i am trying to find out how to write a dat file that will be able to import splines into Catia. These splines when imported are supposed to act like meshes on a structure, that is, picture a meshed structure, but instead of mesh it will be splines on it. so right now i thought to learn a macro that exports a few splines i created on a structure into a text(.dat) file. but i have been having troubles with the macro i have as it asks me to select a spline, but wont allow me to click on the spline in spec tree. The thing is that i have lots of splines and i would like the macro to just select splines automatically without asking and export them..... PLS HELP ME. thanks alot.
So here is the code:
Sub CATMain()
'*** *** Definition Variables
Dim CtrlPoint()
Dim oCoordinates(1)
Dim StartKrit As Integer
'*** Query document type ***
StartKrit = 0
Set oDoc = CATIA.ActiveDocument
ObjType = TypeName(oDoc)
If ObjType = "PartDocument" Then
DocType = "Part"
StartKrit = 1
ElseIf ObjType = "DrawingDocument" Then
DocType = "Drawing "
StartKrit = 1
End If
If StartKrit = 0 Then
box = MsgBox(" The active document is neither a CATPart still CATDrawing! " + Chr(10) + _
" The macro can not continue and will now exit " + Chr(10) + _
"Please select a CATPart or a CATDrawing and start the macro again!", vbCritical + vbOKOnly, "incorrect document type")
Exit Sub
End If
'*** Create the * .txt files ***
StorePath = "C: \"
StoreName = "Splinekoordinaten" & Date
Set fs = CreateObject("Scripting.FileSystemObject")
If fs.FileExists(StorePath & StoreName & ".txt ") = True Then
box = MsgBox(" file ==> " + StorePath + StoreName + " <== already exists! " + Chr(10) + " Do you want to overwrite the file? ", vbCritical + vbYesNo, "file already exists ")
If box = vbNo Then
box = MsgBox(" The macro is now finished ", vbInformation + vbOKOnly, " the user stops ")
Exit Sub
End If
End If
Set A = fs.CreateTextFile("D:\school\INTERNSHIP\Macro\Newest.txt ", True)
A.WriteLine (" points coordinates of a spline ")
A.WriteLine (" ")
If DocType = " Part " Then
A.WriteLine (" name of CATParts: " & oDoc.Name)
ElseIf DocType = " Drawing " Then
A.WriteLine ("name of CATDrawing:" & oDoc.Name)
End If
A.WriteLine ("")
'*** Readout from the CATDrawing ***
If DocType = "Drawing" Then
Dim otype2D(0)
Dim Selection
Set mysel = oDoc.Selection
mysel.Clear
otype2D(0) = "Spline2D"
mysel.Clear
box = MsgBox(" Please select now the spline ", vbInformation + vbOKCancel, " spline Select ")
If box = vbCancel Then
box = MsgBox(" you have the selection canceled " + Chr(10) + _
" the macro is now finished! ", vbCritical, "abort by user")
If fs.FileExists(StorePath & StoreName & ".txt") = True Then
A.Close
fs.DeleteFile (StorePath & StoreName & ".txt")
End If
Exit Sub
End If
Selection = mysel.SelectElement2(otype2D, "Please select the spline", False)
If Selection = "Normal" Then
oSplineName = mysel.Item(1).Value.Name
Set oSpline = mysel.Item(1).Value
A.WriteLine ("name of the selected spline:" & oSplineName)
A.WriteLine ("")
A.WriteLine ("")
Else
box = MsgBox("you have canceled the selection" + Chr(10) + _
"the macro is now finished! ", vbCritical, " abort by user ")
If fs.FileExists(StorePath & StoreName & " .txt ") = True Then
A.Close
fs.DeleteFile (StorePath & StoreName & " .txt ")
End If
Exit Sub
End If
mysel.Clear
Set QuCtrlP = oSpline.EndPoint
QuCtrlPRaw = QuCtrlP.Name
QuCtrlPSemi = Split(QuCtrlPRaw, ".")
QuCtrlPFin = QuCtrlPSemi(1) - 1
ReDim Preserve CtrlPoint(QuCtrlPFin)
For j = 0 To QuCtrlPFin
Set CtrlPoint(j) = oSpline.GetItem("Ktrl-point." & j + 1)
CtrlPoint(j).GetCoordinates oCoordinates
A.WriteLine ("point" & j + 1 & "X / Y")
A.WriteLine (oCoordinates(0))
A.WriteLine (oCoordinates(1))
A.WriteLine ("")
Next
'*** readout from the CATPart ***
ElseIf DocType = "Part" Then
Dim otype3D(0)
Set mysel = oDoc.Selection
mysel.Clear
otype3D(0) = "Spline2D"
mysel.Clear
box = MsgBox("Please select now the spline", vbInformation + vbOKCancel, "spline Select")
If box = vbCancel Then
box = MsgBox("you have canceled the selection" + Chr(10) + _
"The macro is now finished!", vbCritical, "abort by user")
If fs.FileExists(StorePath & StoreName & ".txt") = True Then
A.Close
fs.DeleteFile (StorePath & StoreName & ".txt ")
End If
Exit Sub
End If
Selection = mysel.SelectElement2(otype3D, " Please select the spline ", False)
If Selection = " Normal " Then
oSplineName = mysel.Item(1).Value.Name
Set oSpline = mysel.Item(1).Value
A.WriteLine ("name of the selected spline:" & oSplineName)
A.WriteLine ("")
A.WriteLine ("")
Else
box = MsgBox("you have canceled the selection" + Chr(10) + _
"The macro is now finished!", vbCritical, "abort by user")
If fs.FileExists(StorePath & StoreName & ".txt") = True Then
A.Close
fs.DeleteFile (StorePath & StoreName & " .txt ")
End If
Exit Sub
End If
mysel.Clear
Set QuCtrlP = oSpline.EndPoint
QuCtrlPRaw = QuCtrlP.Name
QuCtrlPSemi = Split(QuCtrlPRaw, " ")
QuCtrlPFin = QuCtrlPSemi(1) - 1
ReDim Preserve CtrlPoint(QuCtrlPFin)
For j = 0 To QuCtrlPFin
Set CtrlPoint(j) = oSpline.GetItem("Ktrl-point." & j + 1)
CtrlPoint(j).GetCoordinates oCoordinates
A.WriteLine ("point" & j + 1 & "X / Y")
A.WriteLine (oCoordinates(0))
A.WriteLine (oCoordinates(1))
A.WriteLine ("")
Next
End If
'**** Issue Storage Location ****
Ml = "The macro has completed successfully"
M2 = "The * .txt file is saved under the following path:"
M2_ZU_1 = "==>"
M2_ZU_2 = "<== "
M3 = " Are you in the path now oeffnen? "
Title = "memory data"
skin = vbInformation + vbYesNo
query = MsgBox(Ml + Chr(10) + Chr(10) + M2 + Chr(10) + Chr(10) + M2_ZU_1 + StorePath + StoreName + M2_ZU_2 + Chr(10) + Chr(10) + M3, skin, Title)
If query = vbYes Then
ExplorerPath = "C: \ WINDOWS \ explorer.exe"
Explorer = CATIA.SystemService.ExecuteProcessus(ExplorerPath & "" & StorePath)
End If
End Sub
Your selectelement2 filter is set for spline2D, are you selected sketch splines or 3d splines?
If you are working with 3d splines like it sounds, you want to use this code:
mysel.Clear
otype3D(0) = "HybridShapeSpline"
mysel.Clear
box = MsgBox("Please select now the spline", vbInformation + vbOKCancel, "spline Select")
If box = vbCancel Then
box = MsgBox("you have canceled the selection" + Chr(10) + _
"The macro is now finished!", vbCritical, "abort by user")
If fs.FileExists(StorePath & StoreName & ".txt") = True Then
A.Close
fs.DeleteFile (StorePath & StoreName & ".txt ")
End If
Exit Sub
End If
Selection = mysel.SelectElement2(otype3D, " Please select the spline ", False)
You'll find more help on www.coe.org, there is a significant group of CATIA automators there.
For various reasons, I'm stuck in Access 97 and need to get only the path part of a full pathname.
For example, the name
c:\whatever dir\another dir\stuff.mdb
should become
c:\whatever dir\another dir\
This site has some suggestions on how to do it:
http://www.ammara.com/access_image_faq/parse_path_filename.html
But they seem rather hideous. There must be a better way, right?
You can do something simple like: Left(path, InStrRev(path, "\"))
Example:
Function GetDirectory(path)
GetDirectory = Left(path, InStrRev(path, Application.PathSeparator))
End Function
I always used the FileSystemObject for this sort of thing. Here's a little wrapper function I used. Be sure to reference the Microsoft Scripting Runtime.
Function StripFilename(sPathFile As String) As String
'given a full path and file, strip the filename off the end and return the path
Dim filesystem As New FileSystemObject
StripFilename = filesystem.GetParentFolderName(sPathFile) & "\"
Exit Function
End Function
This seems to work. The above doesn't in Excel 2010.
Function StripFilename(sPathFile As String) As String
'given a full path and file, strip the filename off the end and return the path
Dim filesystem As Object
Set filesystem = CreateObject("Scripting.FilesystemObject")
StripFilename = filesystem.GetParentFolderName(sPathFile) & "\"
Exit Function
End Function
If you're just needing the path of the MDB currently open in the Access UI, I'd suggest writing a function that parses CurrentDB.Name and then stores the result in a Static variable inside the function. Something like this:
Public Function CurrentPath() As String
Dim strCurrentDBName As String
Static strPath As String
Dim i As Integer
If Len(strPath) = 0 Then
strCurrentDBName = CurrentDb.Name
For i = Len(strCurrentDBName) To 1 Step -1
If Mid(strCurrentDBName, i, 1) = "\" Then
strPath = Left(strCurrentDBName, i)
Exit For
End If
Next
End If
CurrentPath = strPath
End Function
This has the advantage that it only loops through the name one time.
Of course, it only works with the file that's open in the user interface.
Another way to write this would be to use the functions provided at the link inside the function above, thus:
Public Function CurrentPath() As String
Static strPath As String
If Len(strPath) = 0 Then
strPath = FolderFromPath(CurrentDB.Name)
End If
CurrentPath = strPath
End Function
This makes retrieving the current path very efficient while utilizing code that can be used for finding the path for any filename/path.
vFilename="C:\Informes\Indicadores\Program\Ind_Cont_PRv.txt"
vDirFile = Replace(vFilename, Dir(vFileName, vbDirectory), "")
' Result=C:\Informes\Indicadores_Contraloria\Programa\Versiones anteriores\
left(currentdb.Name,instr(1,currentdb.Name,dir(currentdb.Name))-1)
The Dir function will return only the file portion of the full path. Currentdb.Name is used here, but it could be any full path string.
If you are confident in your input parameters, you can use this single line of code which uses the native Split and Join functions and Excel native Application.pathSeparator.
Split(Join(Split(strPath, "."), Application.pathSeparator), Application.pathSeparator)
If you want a more extensive function, the code below is tested in Windows and should also work on Mac (though not tested). Be sure to also copy the supporting function GetPathSeparator, or modify the code to use Application.pathSeparator. Note, this is a first draft; I should really refactor it to be more concise.
Private Sub ParsePath2Test()
'ParsePath2(DrivePathFileExt, -2) returns a multi-line string for debugging.
Dim p As String, n As Integer
Debug.Print String(2, vbCrLf)
If True Then
Debug.Print String(2, vbCrLf)
Debug.Print ParsePath2("", -2)
Debug.Print ParsePath2("C:", -2)
Debug.Print ParsePath2("C:\", -2)
Debug.Print ParsePath2("C:\Windows", -2)
Debug.Print ParsePath2("C:\Windows\notepad.exe", -2)
Debug.Print ParsePath2("C:\Windows\SysWOW64", -2)
Debug.Print ParsePath2("C:\Windows\SysWOW64\", -2)
Debug.Print ParsePath2("C:\Windows\SysWOW64\AcLayers.dll", -2)
Debug.Print ParsePath2("C:\Windows\SysWOW64\.fakedir", -2)
Debug.Print ParsePath2("C:\Windows\SysWOW64\fakefile.ext", -2)
End If
If True Then
Debug.Print String(1, vbCrLf)
Debug.Print ParsePath2("\Windows", -2)
Debug.Print ParsePath2("\Windows\notepad.exe", -2)
Debug.Print ParsePath2("\Windows\SysWOW64", -2)
Debug.Print ParsePath2("\Windows\SysWOW64\", -2)
Debug.Print ParsePath2("\Windows\SysWOW64\AcLayers.dll", -2)
Debug.Print ParsePath2("\Windows\SysWOW64\.fakedir", -2)
Debug.Print ParsePath2("\Windows\SysWOW64\fakefile.ext", -2)
End If
If True Then
Debug.Print String(1, vbCrLf)
Debug.Print ParsePath2("Windows\notepad.exe", -2)
Debug.Print ParsePath2("Windows\SysWOW64", -2)
Debug.Print ParsePath2("Windows\SysWOW64\", -2)
Debug.Print ParsePath2("Windows\SysWOW64\AcLayers.dll", -2)
Debug.Print ParsePath2("Windows\SysWOW64\.fakedir", -2)
Debug.Print ParsePath2("Windows\SysWOW64\fakefile.ext", -2)
Debug.Print ParsePath2(".fakedir", -2)
Debug.Print ParsePath2("fakefile.txt", -2)
Debug.Print ParsePath2("fakefile.onenote", -2)
Debug.Print ParsePath2("C:\Personal\Workspace\Code\PythonVenvs\xlwings_test\.idea", -2)
Debug.Print ParsePath2("Windows", -2) ' Expected to raise error 52
End If
If True Then
Debug.Print String(2, vbCrLf)
Debug.Print "ParsePath2 ""\Windows\SysWOW64\fakefile.ext"" with different ReturnType values"
Debug.Print , "{empty}", "D", ParsePath2("Windows\SysWOW64\fakefile.ext")(1)
Debug.Print , "0", "D", ParsePath2("Windows\SysWOW64\fakefile.ext", 0)(1)
Debug.Print , "1", "ext", ParsePath2("Windows\SysWOW64\fakefile.ext", 1)
Debug.Print , "10", "file", ParsePath2("Windows\SysWOW64\fakefile.ext", 10)
Debug.Print , "11", "file.ext", ParsePath2("Windows\SysWOW64\fakefile.ext", 11)
Debug.Print , "100", "path", ParsePath2("Windows\SysWOW64\fakefile.ext", 100)
Debug.Print , "110", "path\file", ParsePath2("Windows\SysWOW64\fakefile.ext", 110)
Debug.Print , "111", "path\file.ext", ParsePath2("Windows\SysWOW64\fakefile.ext", 111)
Debug.Print , "1000", "D", ParsePath2("Windows\SysWOW64\fakefile.ext", 1000)
Debug.Print , "1100", "D:\path", ParsePath2("Windows\SysWOW64\fakefile.ext", 1100)
Debug.Print , "1110", "D:\p\file", ParsePath2("Windows\SysWOW64\fakefile.ext", 1110)
Debug.Print , "1111", "D:\p\f.ext", ParsePath2("Windows\SysWOW64\fakefile.ext", 1111)
On Error GoTo EH:
' This is expected to presetn an error:
p = "Windows\SysWOW64\fakefile.ext"
n = 1010
Debug.Print "1010", "D:\p\file.ext", ParsePath2("Windows\SysWOW64\fakefile.ext", 1010)
On Error GoTo 0
End If
Exit Sub
EH:
Debug.Print , CStr(n), "Error: "; Err.Number, Err.Description
Resume Next
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Function ParsePath2(ByVal DrivePathFileExt As String _
, Optional ReturnType As Integer = 0)
' Writen by Chris Advena. You may modify and use this code provided you leave
' this credit in the code.
' Parses the input DrivePathFileExt string into individual components (drive
' letter, folders, filename and extension) and returns the portions you wish
' based on ReturnType.
' Returns either an array of strings (ReturnType = 0) or an individual string
' (all other defined ReturnType values).
'
' Parameters:
' DrivePathFileExt: The full drive letter, path, filename and extension
' ReturnType: -2 or a string up of to 4 ones with leading or lagging zeros
' (e.g., 0001)
' -2: special code for debugging use in ParsePath2Test().
' Results in printing verbose information to the Immediate window.
' 0: default: Array(driveStr, pathStr, fileStr, extStr)
' 1: extension
' 10: filename stripped of extension
' 11: filename.extension, excluding drive and folders
' 100: folders, excluding drive letter filename and extension
' 111: folders\filename.extension, excluding drive letter
' 1000: drive leter only
' 1100: drive:\folders, excluding filename and extension
' 1110: drive:\folders\filename, excluding extension
' 1010, 0101, 1001: invalid ReturnTypes. Will result raise error 380, Value
' is not valid.
Dim driveStr As String, pathStr As String
Dim fileStr As String, extStr As String
Dim drivePathStr As String
Dim pathFileExtStr As String, fileExtStr As String
Dim s As String, cnt As Integer
Dim i As Integer, slashStr As String
Dim dotLoc As Integer, slashLoc As Integer, colonLoc As Integer
Dim extLen As Integer, fileLen As Integer, pathLen As Integer
Dim errStr As String
DrivePathFileExt = Trim(DrivePathFileExt)
If DrivePathFileExt = "" Then
fileStr = ""
extStr = ""
fileExtStr = ""
pathStr = ""
pathFileExtStr = ""
drivePathStr = ""
GoTo ReturnResults
End If
' Determine if Dos(/) or UNIX(\) slash is used
slashStr = GetPathSeparator(DrivePathFileExt)
' Find location of colon, rightmost slash and dot.
' COLON: colonLoc and driveStr
colonLoc = 0
driveStr = ""
If Mid(DrivePathFileExt, 2, 1) = ":" Then
colonLoc = 2
driveStr = Left(DrivePathFileExt, 1)
End If
#If Mac Then
pathFileExtStr = DrivePathFileExt
#Else ' Windows
pathFileExtStr = ""
If Len(DrivePathFileExt) > colonLoc _
Then pathFileExtStr = Mid(DrivePathFileExt, colonLoc + 1)
#End If
' SLASH: slashLoc, fileExtStr and fileStr
' Find the rightmost path separator (Win backslash or Mac Fwdslash).
slashLoc = InStrRev(DrivePathFileExt, slashStr, -1, vbBinaryCompare)
' DOT: dotLoc and extStr
' Find rightmost dot. If that dot is not part of a relative reference,
' then set dotLoc. dotLoc is meant to apply to the dot before an extension,
' NOT relative path reference dots. REl ref dots appear as "." or ".." at
' the very leftmost of the path string.
dotLoc = InStrRev(DrivePathFileExt, ".", -1, vbTextCompare)
If Left(DrivePathFileExt, 1) = "." And dotLoc <= 2 Then dotLoc = 0
If slashLoc + 1 = dotLoc Then
dotLoc = 0
If Len(extStr) = 0 And Right(pathFileExtStr, 1) <> slashStr _
Then pathFileExtStr = pathFileExtStr & slashStr
End If
#If Not Mac Then
' In windows, filenames cannot end with a dot (".").
If dotLoc = Len(DrivePathFileExt) Then
s = "Error in FileManagementMod.ParsePath2 function. " _
& "DrivePathFileExt " & DrivePathFileExt _
& " cannot end iwth a dot ('.')."
Err.Raise 52, "FileManagementMod.ParsePath2", s
End If
#End If
' extStr
extStr = ""
If dotLoc > 0 And (dotLoc < Len(DrivePathFileExt)) _
Then extStr = Mid(DrivePathFileExt, dotLoc + 1)
' fileExtStr
fileExtStr = ""
If slashLoc > 0 _
And slashLoc < Len(DrivePathFileExt) _
And dotLoc > slashLoc Then
fileExtStr = Mid(DrivePathFileExt, slashLoc + 1)
End If
' Validate the input: DrivePathFileExt
s = ""
#If Mac Then
If InStr(1, DrivePathFileExt, ":") > 0 Then
s = "DrivePathFileExt ('" & DrivePathFileExt _
& "')has invalid format. " _
& "UNIX/Mac filenames cannot contain a colon ('.')."
End If
#End If
If Not colonLoc = 0 And slashLoc = 0 And dotLoc = 0 _
And Left(DrivePathFileExt, 1) <> slashStr _
And Left(DrivePathFileExt, 1) <> "." Then
s = "DrivePathFileExt ('" & DrivePathFileExt _
& "') has invalid format. " _
& "Good example: 'C:\folder\file.txt'"
ElseIf colonLoc <> 0 And colonLoc <> 2 Then
' We are on Windows and there is a colon; it can only be
' in position 2.
s = "DrivePathFileExt ('" & DrivePathFileExt _
& "') has invalid format. " _
& "In the Windows operating system, " _
& "a colon (':') can only be the second character '" _
& "of a valid file path. "
ElseIf Left(DrivePathFileExt, 1) = ":" _
Or InStr(3, DrivePathFileExt, ":", vbTextCompare) > 0 Then
'If path contains a drive letter, it must contain at least one slash.
s = "DrivePathFileExt ('" & DrivePathFileExt _
& "') has invalid format. " _
& "Colon can only appear in the second character position." _
& slashStr & "')."
ElseIf colonLoc > 0 And slashLoc = 0 _
And Len(DrivePathFileExt) > 2 Then
'If path contains a drive letter, it must contain at least one slash.
s = "DrivePathFileExt ('" & DrivePathFileExt _
& "') has invalid format. " _
& "The last dot ('.') cannot be before the last file separator '" _
& slashStr & "')."
ElseIf colonLoc = 2 _
And InStr(1, DrivePathFileExt, slashStr, vbTextCompare) = 0 _
And Len(DrivePathFileExt) > 2 Then
' There is a colon, but no file separator (slash). This is invalid.
s = "DrivePathFileExt ('" & DrivePathFileExt _
& "') has invalid format. " _
& "If a drive letter is included, then there must be at " _
& "least one file separator character ('" & slashStr & "')."
ElseIf Len(driveStr) > 0 And Len(DrivePathFileExt) > 2 And slashLoc = 0 Then
' If path contains a drive letter and is more than 2 character long
' (e.g., 'C:'), it must contain at least one slash.
s = "DrivePathFileExt cannot contain a drive letter but no path separator."
End If
If Len(s) > 0 Then
End If
' Determine if DrivePathFileExt = DrivePath
' or = Path (with no fileStr or extStr components).
If Right(DrivePathFileExt, 1) = slashStr _
Or slashLoc = 0 _
Or dotLoc = 0 _
Or (dotLoc > 0 And dotLoc <= slashLoc + 1) Then
' If rightmost character is the slashStr, then no fileExt exists, just drivePath
' If no dot found, then no extension. Assume a folder is after the last slashstr,
' not a filename.
' If a dot is found (extension exists),
' If a rightmost dot appears one-char to the right of the rightmost slash
' or anywhere before (left) of that, it is not a file/ext separator. Exmaple:
' 'C:\folder1\.folder2' Then
' If no slashes, then no fileExt exists. It must just be a driveletter.
' DrivePathFileExt contains no file or ext name.
fileStr = ""
extStr = ""
fileExtStr = ""
pathStr = pathFileExtStr
drivePathStr = DrivePathFileExt
GoTo ReturnResults
Else
' fileStr
fileStr = ""
If slashLoc > 0 Then
If Len(extStr) = 0 Then
fileStr = fileExtStr
Else
' length of filename excluding dot and extension.
i = Len(fileExtStr) - Len(extStr) - 1
fileStr = Left(fileExtStr, i)
End If
Else
s = "Error in FileManagementMod.ParsePath2 function. " _
& "*** Unhandled scenario: find fileStr when slashLoc = 0. *** "
Err.Raise 52, "FileManagementMod.ParsePath2", s
End If
' pathStr
pathStr = ""
' length of pathFileExtStr excluding fileExt.
i = Len(pathFileExtStr) - Len(fileExtStr)
pathStr = Left(pathFileExtStr, i)
' drivePathStr
drivePathStr = ""
' length of DrivePathFileExt excluding dot and extension.
i = Len(DrivePathFileExt) - Len(fileExtStr)
drivePathStr = Left(DrivePathFileExt, i)
End If
ReturnResults:
' ReturnType uses a 4-digit binary code: dpfe = drive path file extension,
' where 1 = return in array and 0 = do not return in array
' -2, and 0 are special cases that do not follow the code.
' Note: pathstr is determined with the tailing slashstr
If Len(drivePathStr) > 0 And Right(drivePathStr, 1) <> slashStr _
Then drivePathStr = drivePathStr & slashStr
If Len(pathStr) > 0 And Right(pathStr, 1) <> slashStr _
Then pathStr = pathStr & slashStr
#If Not Mac Then
' Including this code add a slash to the beginnning where missing.
' the downside is that it would create an absolute path where a
' sub-path of the current folder is intended.
'If colonLoc = 0 Then
' If Len(drivePathStr) > 0 And Not IsIn(Left(drivePathStr, 1), slashStr, ".") _
Then drivePathStr = slashStr & drivePathStr
' If Len(pathStr) > 0 And Not IsIn(Left(pathStr, 1), slashStr, ".") _
Then pathStr = slashStr & pathStr
' If Len(pathFileExtStr) > 0 And Not IsIn(Left(pathFileExtStr, 1), slashStr, ".") _
Then pathFileExtStr = slashStr & pathFileExtStr
'End If
#End If
Select Case ReturnType
Case -2 ' used for ParsePath2Test() only.
ParsePath2 = "DrivePathFileExt " _
& CStr(Nz(DrivePathFileExt, "{empty string}")) _
& vbCrLf & " " _
& "-------------- -----------------------------------------" _
& vbCrLf & " " & "D:\Path\ " & drivePathStr _
& vbCrLf & " " & "\path[\file.ext] " & pathFileExtStr _
& vbCrLf & " " & "\path\ " & pathStr _
& vbCrLf & " " & "file.ext " & fileExtStr _
& vbCrLf & " " & "file " & fileStr _
& vbCrLf & " " & "ext " & extStr _
& vbCrLf & " " & "D " & driveStr _
& vbCrLf & vbCrLf
' My custom debug printer prints to Immediate winodw and log file.
' Dbg.Prnt 2, ParsePath2
Debug.Print ParsePath2
Case 1 '0001: ext
ParsePath2 = extStr
Case 10 '0010: file
ParsePath2 = fileStr
Case 11 '0011: file.ext
ParsePath2 = fileExtStr
Case 100 '0100: path
ParsePath2 = pathStr
Case 110 '0110: (path, file)
ParsePath2 = pathStr & fileStr
Case 111 '0111:
ParsePath2 = pathFileExtStr
Case 1000
ParsePath2 = driveStr
Case 1100
ParsePath2 = drivePathStr
Case 1110
ParsePath2 = drivePathStr & fileStr
Case 1111
ParsePath2 = DrivePathFileExt
Case 1010, 101, 1001
s = "Error in FileManagementMod.ParsePath2 function. " _
& "Value of Paramter (ReturnType = " _
& CStr(ReturnType) & ") is not valid."
Err.Raise 380, "FileManagementMod.ParsePath2", s
Case Else ' default: 0
ParsePath2 = Array(driveStr, pathStr, fileStr, extStr)
End Select
End Function
Supporting function GetPathSeparatorTest extends the native Application.pathSeparator (or bypasses when needed) to work on Mac and Win. It can also takes an optional path string and will try to determine the path separator used in the string (favoring the OS native path separator).
Private Sub GetPathSeparatorTest()
Dim s As String
Debug.Print "GetPathSeparator(s):"
Debug.Print "s not provided: ", GetPathSeparator
s = "C:\folder1\folder2\file.ext"
Debug.Print "s = "; s, GetPathSeparator(DrivePathFileExt:=s)
s = "C:/folder1/folder2/file.ext"
Debug.Print "s = "; s, GetPathSeparator(DrivePathFileExt:=s)
End Sub
Function GetPathSeparator(Optional DrivePathFileExt As String = "") As String
' by Chris Advena
' Finds the path separator from a string, DrivePathFileExt.
' If DrivePathFileExt is not provided, return the operating system path separator
' (Windows = backslash, Mac = forwardslash).
' Mac/Win compatible.
' Initialize
Dim retStr As String: retStr = ""
Dim OSSlash As String: OSSlash = ""
Dim OSOppositeSlash As String: OSOppositeSlash = ""
Dim PathFileExtSlash As String
GetPathSeparator = ""
retStr = ""
' Determine if OS expects fwd or back slash ("/" or "\").
On Error GoTo EH
OSSlash = Application.pathSeparator
If DrivePathFileExt = "" Then
' Input parameter DrivePathFileExt is empty, so use OS file separator.
retStr = OSSlash
Else
' Input parameter DrivePathFileExt provided. See if it contains / or \.
' Set OSOppositeSlash to the opposite slash the OS expects.
OSOppositeSlash = "\"
If OSSlash = "\" Then OSOppositeSlash = "/"
' If DrivePathFileExt does NOT contain OSSlash
' and DOES contain OSOppositeSlash, return OSOppositeSlash.
' Otherwise, assume OSSlash is correct.
retStr = OSSlash
If InStr(1, DrivePathFileExt, OSSlash, vbTextCompare) = 0 _
And InStr(1, DrivePathFileExt, OSOppositeSlash, vbTextCompare) > 0 Then
retStr = OSOppositeSlash
End If
End If
GetPathSeparator = retStr
Exit Function
EH:
' Application.PathSeparator property does not exist in Access,
' so get it the slightly less easy way.
#If Mac Then ' Application.PathSeparator doesn't seem to exist in Access...
OSSlash = "/"
#Else
OSSlash = "\"
#End If
Resume Next
End Function
Supporting function (actually commented out, so you can skip this if you don't plan to use it).
Sub IsInTest()
' IsIn2 is case insensitive
Dim StrToFind As String, arr As Variant
arr = Array("Me", "You", "Dog", "Boo")
StrToFind = "doG"
Debug.Print "Is '" & CStr(StrToFind) & "' in list (expect True): " _
, IsIn(StrToFind, "Me", "You", "Dog", "Boo")
StrToFind = "Porcupine"
Debug.Print "Is '" & CStr(StrToFind) & "' in list (expect False): " _
, IsIn(StrToFind, "Me", "You", "Dog", "Boo")
End Sub
Function IsIn(ByVal StrToFind, ParamArray StringArgs() As Variant) As Boolean
' StrToFind: the string to find in the list of StringArgs()
' StringArgs: 1-dimensional array containing string values.
' Built for Strings, but actually works with other data types.
Dim arr As Variant
arr = StringArgs
IsIn = Not IsError(Application.Match(StrToFind, arr, False))
End Function
Try this function:
Function FolderPath(FilePath As String) As String
'--------------------------------------------------
'Returns the folder path form the file path.
'Written by: Christos Samaras
'Date: 06/11/2013
'--------------------------------------------------
Dim FileName As String
With WorksheetFunction
FileName = Mid(FilePath, .Find("*", .Substitute(FilePath, "\", "*", Len(FilePath) - _
Len(.Substitute(FilePath, "\", "")))) + 1, Len(FilePath))
End With
FolderPath = Left(FilePath, Len(FilePath) - Len(FileName) - 1)
End Function
If you don't want to remove the last backslash "\" at the end of the folder's path, change the last line with this:
FolderPath = Left(FilePath, Len(FilePath) - Len(FileName))
Example:
FolderPath("C:\Users\Christos\Desktop\LAT Analysers Signal Correction\1\TP 14_03_2013_5.csv")
gives:
C:\Users\Christos\Desktop\LAT Analysers Signal Correction\1
or
C:\Users\Christos\Desktop\LAT Analysers Signal Correction\1\
in the second case (note that there is a backslash at the end).
I hope it helps...
Use these codes and enjoy it.
Public Function GetDirectoryName(ByVal source As String) As String()
Dim fso, oFolder, oSubfolder, oFile, queue As Collection
Set fso = CreateObject("Scripting.FileSystemObject")
Set queue = New Collection
Dim source_file() As String
Dim i As Integer
queue.Add fso.GetFolder(source) 'obviously replace
Do While queue.Count > 0
Set oFolder = queue(1)
queue.Remove 1 'dequeue
'...insert any folder processing code here...
For Each oSubfolder In oFolder.SubFolders
queue.Add oSubfolder 'enqueue
Next oSubfolder
For Each oFile In oFolder.Files
'...insert any file processing code here...
'Debug.Print oFile
i = i + 1
ReDim Preserve source_file(i)
source_file(i) = oFile
Next oFile
Loop
GetDirectoryName = source_file
End Function
And here you can call function:
Sub test()
Dim s
For Each s In GetDirectoryName("C:\New folder")
Debug.Print s
Next
End Sub