Delete File based on DateCreated or filename which consist of date - vbscript

I have to delete data based on its filename. This is what the files look like:
Nostro_BO_FCC_130317.csv [130317 is a created date]
Nostro_BO_FCC_120317.csv
Nostro_BO_FCC_110317.csv
Nostro_BO_FCC_100317.csv
Nostro_BO_FCC_090317.csv
and this is where the data located: D:\BDI\CTS\Data\Nostro\BO FCC\
I have developed VBScript to delete the file but it does not work at all. All I want is to delete the file which below 2 days since current date (13/03/2017).
This is my VBScript:
Dim infolder
Dim ad, intcount, i, str, Postdate, Uploaddate, fileExists, ExpireDate
Dim sql_query, rs, rsU
Dim ObjFSO, objFile, OFile, OfPath, osf, MM, DD
Set ad = CreateObject("ADODB.Connection")
ad.Provider = "sqloledb"
If Len(Month(varDate)) = 1 then
MM = "0" & Month(varDate)
Else
MM = Month(varDate)
End If
If Len(Day(varDate)) = 1 then
DD = "0" & Day(varDate)
Else
DD = Day(varDate)
End If
PostDate = Year(varDate) & MM & DD
Uploaddate = DD & MM & Right(Year(varDate), 2)
ExpireDate = CDate(DD) < Date - 1 & MM & Right(Year(varDate), 2)
ad.CursorLocation = 3
ad.Open propstr
Set osf = CreateObject("Scripting.FileSystemObject")
OfPath = "D:\BDI\CTS\Data\Nostro\BO FCC\"
'this below my logic steven
Set infolder = osf.GetFolder(OfPath)
Set OFile = Nothing
fileExists = True
fullfilename = "Nostro_BO_FCC_"& Uploaddate &".csv"
'create file if not exits and delete if exits then create again
If Not osf.FileExists(OFPath & fullfilename) Then
Set OFile = osf.CreateTextFile(OFPath & fullfilename, True)
Set OFile = Nothing
End If
For Each file In infolder.Files
If DateDiff("d", file.DateCreated, Date) < Date -2 Then
' oFSO.DeleteFile(oFile)
'If osf.FileExists(OfPath & "Nostro_BO_FCC_" & ExpireDate & ".csv") Then
'osf.DeleteFile OfPath & "Nostro_BO_FCC_" & ExpireDate & ".csv"
file.Delete(True)
End If
Next

CDate(DD) < Date -1 & MM & Right(Year(varDate),2) isn't going to do what you apparently expect it to do. I already told you that when answering your previous question where you used a similar construct.
If you want to compare date strings with a < or > operator, the strings must be in a format where string order and date order are identical. That is not the case for your DDMMYY format. Because of that you basically have two options:
Since you have a small number of valid dates you could build reference filenames:
Function dd(s) : dd = Right("00" & s, 2) : End Function
d1 = Date
d2 = d1 - 1
d3 = d1 - 2
fn1 = "Nostro_BO_FCC_"& dd(Day(d1)) & dd(Month(d1)) && Right(Year(d1), 2) &".csv"
fn2 = "Nostro_BO_FCC_"& dd(Day(d2)) & dd(Month(d2)) && Right(Year(d2), 2) &".csv"
fn3 = "Nostro_BO_FCC_"& dd(Day(d3)) & dd(Month(d3)) && Right(Year(d3), 2) &".csv"
and delete all files whose name isn't among them:
For Each f In infolder.Files
If f.Name <> fn1 And f.Name <> fn2 And f.Name <> fn3 Then
f.Delete
End If
Next
A more generic approach is to parse the date from each filename:
a = Split(osf.GetBaseName(f), "_")
ds = a(UBound(a))
d = DateSerial(Mid(ds, 5, 2), Mid(ds, 3, 2), Mid(ds, 1, 2))
and delete all files with a date below your reference date:
refDate = Date - 2
For Each f In infolder.Files
...
If d < refDate Then
f.Delete
End If
Next
Edit: If you want to compare the files' creation date against a reference date you can do that like this:
refDate = Date - 2
For Each f In infolder.Files
If f.DateCreated < refDate Then
f.Delete
End If
Next

Related

VBscript - How to save TXT in UTF-8

how can I write UTF-8 encoded strings to a textfile from VBScript? I have tried some variations but no success. So I need the text file saved in UTF-8 format. thanks in advance for your all help.
Output :
CN=™ser1 D˜,OU=TEST,OU=TEST,OU=Users,OU=contoso,DC=contoso,DC=local;10.01.2012 01:00:00
CN=Gšbson ¦LU,OU=TEST,OU=TEST,OU=Users,OU=contoso,DC=contoso,DC=local;20.12.2016 18:55:51
CN=™ZL €ET˜,OU=TEST,OU=TEST,OU=Users,OU=contoso,DC=contoso,DC=local;27.08.2013
type ExpReport.txt (as you can see no special characters)
CN=ser1 D,OU=TEST,OU=TEST,OU=Users,OU=contoso,DC=contoso,DC=local;10.01.2012 01:00:00
CN=Gbson LU,OU=TEST,OU=TEST,OU=Users,OU=contoso,DC=contoso,DC=local;20.12.2016 18:55:51
CN=ZL ET,OU=TEST,OU=TEST,OU=Users,OU=contoso,DC=contoso,DC=local;27.08.2013
cscript //nologo AcctsExpire.vbs > ExpReport.txt
Here is my code :
Option Explicit
Dim adoConnection, adoCommand
Dim objRootDSE, strDNSDomain, strFilter, strQuery, adoRecordset
Dim strDN, objShell, lngBiasKey, lngBias
Dim lngDate, objDate, dtmAcctExp, k
' Obtain local time zone bias from machine registry.
Set objShell = CreateObject("Wscript.Shell")
lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\" _
& "TimeZoneInformation\ActiveTimeBias")
If (UCase(TypeName(lngBiasKey)) = "LONG") Then
lngBias = lngBiasKey
ElseIf (UCase(TypeName(lngBiasKey)) = "VARIANT()") Then
lngBias = 0
For k = 0 To UBound(lngBiasKey)
lngBias = lngBias + (lngBiasKey(k) * 256^k)
Next
End If
' Use ADO to search the domain for all users.
Set adoConnection = CreateObject("ADODB.Connection")
Set adoCommand = CreateObject("ADODB.Command")
adoConnection.Provider = "ADsDSOOBject"
adoConnection.Open "Active Directory Provider"
Set adoCommand.ActiveConnection = adoConnection
' Determine the DNS domain from the RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("DefaultNamingContext")
' Filter to retrieve all user objects with accounts
' that expire.
strFilter = "(&(objectCategory=person)(objectClass=user)" _
& "(!accountExpires=0)(!accountExpires=9223372036854775807))"
strQuery = "<LDAP://" & strDNSDomain & ">;" & strFilter _
& ";distinguishedName,accountExpires;subtree"
' Run the query.
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
Set adoRecordset = adoCommand.Execute
' Enumerate the recordset.
Do Until adoRecordset.EOF
strDN = adoRecordset.Fields("distinguishedName").Value
lngDate = adoRecordset.Fields("accountExpires")
Set objDate = lngDate
dtmAcctExp = Integer8Date(objDate, lngBias)
Wscript.Echo strDN & ";" & dtmAcctExp
adoRecordset.MoveNext
Loop
adoRecordset.Close
' Clean up.
adoConnection.Close
Function Integer8Date(ByVal objDate, ByVal lngBias)
' Function to convert Integer8 (64-bit) value to a date, adjusted for
' local time zone bias.
Dim lngAdjust, lngDate, lngHigh, lngLow
lngAdjust = lngBias
lngHigh = objDate.HighPart
lngLow = objdate.LowPart
' Account for bug in IADslargeInteger property methods.
If (lngLow < 0) Then
lngHigh = lngHigh + 1
End If
If (lngHigh = 0) And (lngLow = 0) Then
lngAdjust = 0
End If
lngDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
+ lngLow) / 600000000 - lngAdjust) / 1440
Integer8Date = CDate(lngDate)
End Function
Last Update :
Issue is resolved.
cscript //nologo AcctsExpire.vbs //U > ExpReport.txt
Also WSCRIPT AcctsExpire.vbs displays correct output.

Invalid procedure call or argument on split mac excel vba

I am not sure why but this cet = Split(strCSV, " - ") causes Run time error 5: Invalid procedure call or argument.
strCSV = Trim(cWk.Range("P" & i)): dt = CDate(CLng(cWk.Range("H" & i)))
where str = "Cap Style:Snapback - CD / Number:07 / Color:First Avenger(+S$1.50) / Box:none - Only Purchase 3 caps and above - Free Box "
Following code works perfectly on windows but it throws error on the above mentioned line
Option Explicit
Option Compare Text
Sub Get_Data()
Application.ScreenUpdating = False
Dim fName, wkB2 As Workbook, cWk As Worksheet, xWk As Worksheet, frowC As Long, i As Long, j As Long, ch As String, num As String
Dim strCSV As String, dt As Date, shtName As String, cet, temp As String, rng As Range, cel As Range, cl As String, rw As Long, toF As String
On Error GoTo Err
fName = Application.GetOpenFilename
If fName <> False Then
Set wkB2 = Workbooks.Open(fName): Set cWk = wkB2.Worksheets(1): frowC = cWk.Range("P" & Rows.Count).End(xlUp).Row
'Cap Style:Baseball - CC / Number:04 / Color:Grey(+S$2) / Box:none - Only Purchase 3 caps and above - Free Box
'Cap Style:SnapBack - CC / Number:04 / Color:Grey(+S$1.50) / Box:none - Only Purchase 3 caps and above - Free Box
For i = 2 To frowC
strCSV = Trim(cWk.Range("P" & i)): dt = CDate(CLng(cWk.Range("H" & i)))
If strCSV <> "" And IsDate(dt) Then
'ERROR cet = Split(strCSV, " - "): temp = cet(LBound(cet)): cet = Split(temp, ":"): shtName = Trim(cet(UBound(cet)))
For Each xWk In ThisWorkbook.Worksheets
If shtName = Trim(xWk.Name) Then
Set rng = xWk.Range("E3:BD3")
For Each cel In rng
If cel.Value = dt Then
cet = Split(cel.Address, "$"): cl = cet(UBound(cet) - 1): Exit For
End If
Next cel
cet = Split(strCSV, "Number:"): temp = cet(UBound(cet)): cet = Split(temp, "/"): num = Trim(cet(LBound(cet)))
cet = Split(strCSV, " / "): temp = cet(LBound(cet)): cet = Split(temp, " - "): ch = Trim(cet(UBound(cet))): ch = ch & "-" & num
Debug.Print "Ch is " & ch
Set rng = xWk.Range("A1:A" & xWk.Range("A" & Rows.Count).End(xlUp).Row)
For Each cel In rng
If cel.Value = ch Then
rw = cel.Row: Exit For
End If
Next cel
cet = Split(strCSV, "Color:"): temp = cet(UBound(cet)): cet = Split(temp, "("): toF = Trim(cet(LBound(cet)))
For j = rw To rw - 10 Step -1
If Trim(xWk.Range("B" & j)) = toF Then
rw = j: Exit For
End If
Next j
Debug.Print "Address is: " & cl & rw & " for row " & i
xWk.Range(cl & rw) = cWk.Range("O" & i)
Exit For
End If
Next xWk
End If
Next i
wkB2.Close False
Else
Exit Sub
End If
Application.ScreenUpdating = True
MsgBox "Done"
Exit Sub
Err:
MsgBox Err.Description
End Sub
Update: SplitString now handle multi-character delimiters.
We conclude that older versions of Mac Office use the equivalent of VB5. Since the Split function was introduced in VB6. An Invalid procedure call or argument is being thrown because the Split function is not available in VB5.
The workaround would be to create a custom function that works like Spli.
Split Replacement Function
Function SplitString(Text As String, Delimiter As String)
Dim arr() As String, s As String
Dim i As Long, iEnd As Long, iStart As Long, length As Long
length = Len(Delimiter)
ReDim Preserve arr(0)
iStart = 1
Do
iEnd = InStr(Mid(Text, iStart), Delimiter) - 1
If iEnd = -1 Then
ReDim Preserve arr(i)
arr(i) = Mid(Text, iStart)
Exit Do
Else
ReDim Preserve arr(i)
arr(i) = Mid(Text, iStart, iEnd)
iStart = iStart + iEnd + length
i = i + 1
End If
Loop Until iStart = 0
SplitString = arr
End Function
Here are the tests that I ran
Sub BatchTest()
Dim strCSV As String, Temp As String, Delimiter As String
Dim a
strCSV = "Cap Style Snapback - CD / Number 07 / Color First Avenger(+S$1.50) / Box none - Only Purchase 3 caps and above - Free Box"
a = SplitString(strCSV, "/")
TestSplit strCSV, " / "
TestSplit strCSV, " /"
TestSplit strCSV, "/"
TestSplit strCSV, " Color First"
End Sub
Sub TestSplit(Text As String, Delimiter As String)
Dim arr As Variant, sReplcement As String
arr = SplitString(Text, Delimiter)
sReplcement = Replace(Text, Delimiter, "|")
Debug.Print sReplcement
Debug.Print Join(arr, "|")
Debug.Print sReplcement = Join(arr, "|")
End Sub
The Results of the tests
Sub TestRegEx()
MsgBox RegexExtract("sdi 99090 dfddf sdi 5666", "(sdi \d+)", ", ") = "sdi 99090, sdi 5666"
End Sub
Function RegexExtract(ByVal text As String, _
ByVal extract_what As String, _
Optional seperator As String = "") As String
Dim i As Long, j As Long
Dim result As String
Dim allMatches As Object
Dim RE As Object
Set RE = CreateObject("vbscript.regexp")
RE.Pattern = extract_what
RE.Global = True
Set allMatches = RE.Execute(text)
For i = 0 To allMatches.count - 1
For j = 0 To allMatches.Item(i).submatches.count - 1
result = result & seperator & allMatches.Item(i).submatches.Item(j)
Next
Next
If Len(result) <> 0 Then
result = Right(result, Len(result) - Len(seperator))
End If
RegexExtract = result
End Function

how can I copy and delete only the files base of modified date in vbscript?

all files from my source file location has been copied in
destination folder.
how can i copy then delete the 2 files only if my
datefrom = 12/07/2014 and my
dateto = 12/09/2014.
filename: date modified
file1 12/07/2014
file2 12/09/2014
file3 01/06/2015
this is my code.
Dim ObjFso
Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim StrSourceLocation
Dim StrDestinationLocation
Dim StrSourceFileName
dim SourceLocation
dim DestinationLocation
dim datefrom, dateto, datectr
datefrom = DateValue("01/01/2015")
dateto = DateValue("01/01/2015")
datefrom = InputBox ("date from: (mm/dd/yyyy)")
dateto = InputBox ("date to: (mm/dd/yyyy)")
StrSourceLocation = InputBox ("source:")
StrDestinationLocation = InputBox ("destination:")
datectr = datefrom
dateto = dateto
intYear=0
intMonth=0
indDay=0
intFileCtr=0
intFileDayCtr=0
SourceLocation = StrSourceLocation + "\*.*"
DestinationLocation = StrDestinationLocation + "\"
Const OverwriteExisting = True
Do Until datectr>dateto
intYear=Year(datectr)
intMonth=Month(datectr)
intDay=Day(datectr)
for each f in objFSO.Getfolder(StrSourceLocation).Files
if Year(f.DateLastModified) = intYear And Month(f.DatelastModified) = intMonth And Day(f.DateLastModified) = intDay Then
objFSO.CopyFile SourceLocation , DestinationLocation, OverwriteExisting
objFSO.DeleteFile(SourceLocation), True
end if
Next
datectr=DateAdd("d", 1, datectr)
datectr = DateValue(datectr)
Loop
I have no idea what you are doing. Dates are simple in VBS.
If DateValue("01/01/1980") < DateValue("01/01/1990") or DateValue("01/01/1980") > DateValue("01/01/1960") then
' blah
End If
Is how to check dates within a range.
There is also the similar DateSerial. Dates are numbers, x days since a day in the past (01/01/100 AD) with time being a a fraction which is a fraction of a day (12 pm is 0.5).

SHGetPathFromIDList does not return pathnames with leading periods

I have some Excel x64 VBA code that gets MP3 files, along with track#, size, length, etc., and puts them in some worksheets. The basic code came from John Walkenbach's page and can be found here: http://spreadsheetpage.com/index.php/file/mp3_file_lister/. I have modified it to run in 64-bit Excel by adding the PtrSafe keyword in the function declarations and changing some data types from Long to either LongLong or LongPtr (and maybe a few others). The code works wonderfully with one not too minor exception, it will not return any files in folders that contain leading periods. For example, I have an album by .38 Special ripped using WMP. The folder is: D:\Users\username\Music\Music.38 Special\Rock & Roll Strategy... This path does not appear in the list generated. I also have: D:\Users\username\Music\Music\Norah Jones...Featuring Nora Jones... and this folder is missing, too (the trailing ellipses represent the list of songs) . I have contacted John Walkenbach via email, and he has no idea why this is happening either.
Here is the code as I've modified it:
Option Explicit
Dim Sht1Row As Integer
Dim Sht2Row As Integer
' By John Walkenbach
' Maybe be distributed freely, but not sold
'API declarations
Declare PtrSafe Function SHGetPathFromIDList Lib "shell32.dll" Alias "SHGetPathFromIDListA" (ByVal pidl As LongPtr, ByVal pszPath As String) As LongPtr
Declare PtrSafe Function SHBrowseForFolder Lib "shell32.dll" Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As LongPtr
Public Type BROWSEINFO
hOwner As LongPtr
pidlRoot As LongPtr
pszDisplayName As String
lpszTitle As String
ulFlags As LongPtr
lpfn As LongPtr
lParam As LongPtr
iImage As LongPtr
End Type
Sub GetAllFiles()
Dim Msg As String
Dim Directory As String
Dim lastRow1C As Integer
Dim lastRow2C As Integer
Dim lastRow1D As Integer
Dim lastRow2D As Integer
Msg = "Select the directory that contains the MP3 files. All subdirectories will be included."
Directory = GetDirectory(Msg)
If Directory = "" Then Exit Sub
If Right(Directory, 1) "\" Then Directory = Directory & "\"
With Sheet1
lastRow1C = .Cells(.Rows.Count, "C").End(xlUp).Row
If lastRow1C lastRow2D Then
.Range("D" & lastRow2D, "F" & lastRow2D).Select
Selection.AutoFill Destination:=Range("D" & lastRow2D, "F" & lastRow2C)
End If
.Range("E2:E" & lastRow2C).Copy
.Range("A2:A" & lastRow2C).PasteSpecial xlPasteValues
Columns("A:J").Sort key1:=Range("G2"), order1:=xlAscending, key2:=Range("H2"), order2:=xlAscending, Header:=xlYes
Range("A1").Select
End With
With Sheet1
Worksheets("Music_Library_Full").Activate
lastRow1C = .Cells(.Rows.Count, "C").End(xlUp).Row
lastRow1D = .Cells(.Rows.Count, "D").End(xlUp).Row
If lastRow1C > lastRow1D Then
.Range("D" & lastRow1D, "F" & lastRow1D).Select
Selection.AutoFill Destination:=Range("D" & lastRow1D, "F" & lastRow1C)
End If
.Range("E2:E" & lastRow1C).Copy
.Range("A2:A" & lastRow1C).PasteSpecial xlPasteValues
Columns("A:J").Sort key1:=Range("G2"), order1:=xlAscending, key2:=Range("H2"), order2:=xlAscending, Header:=xlYes
Range("A1").Select
End With
Application.ScreenUpdating = True
End Sub
Function GetDirectory(Optional Msg) As String
Dim bInfo As BROWSEINFO
Dim path As String
Dim r As String
Dim x As String
Dim pos As Integer
' Root folder = Desktop
bInfo.pidlRoot = 0&
' Title in the dialog
If IsMissing(Msg) Then
bInfo.lpszTitle = "Select a folder."
Else
bInfo.lpszTitle = Msg
End If
' Type of directory to return
bInfo.ulFlags = &H1
' Display the dialog
x = SHBrowseForFolder(bInfo)
' Parse the result
path = Space$(512)
r = SHGetPathFromIDList(ByVal x, ByVal path)
If r Then
pos = InStr(path, Chr$(0))
GetDirectory = Left(path, pos - 1)
Else
GetDirectory = ""
End If
End Function
Public Sub RecursiveDir(ByVal currdir As String)
Dim Dirs() As Variant
Dim NumDirs As Long
Dim FileName As String
Dim PathAndName As String
Dim i As Long
Dim PathName As String
Dim TrackNum As Variant
Dim Genre As String
Dim Duration As Variant
Dim FileSize As Variant
' Make sure path ends in backslash
If Right(currdir, 1) "\" Then currdir = currdir & "\"
' Put column headings on active sheet
Worksheets("Music_Library_Full").Activate
Cells(1, 1) = "Artist & Filename Lookup"
Cells(1, 2) = "Filename Lookup"
Cells(1, 3) = "Full Pathname"
Cells(1, 4) = "Artist"
Cells(1, 5) = "Artist & Filename"
Cells(1, 6) = "Filename"
Cells(1, 7) = "Path"
Cells(1, 8) = "Track#"
Cells(1, 9) = "Duration"
Cells(1, 10) = "Size"
Range("1:1").Font.Bold = True
Range("1:1").Font.Italic = True
Range("1:1").Font.Name = "Consolas"
Worksheets("Best_Greatest").Activate
Cells(1, 1) = "Artist & Filename Lookup"
Cells(1, 2) = "Filename Lookup"
Cells(1, 3) = "Full Pathname"
Cells(1, 4) = "Artist"
Cells(1, 5) = "Artist & Filename"
Cells(1, 6) = "Filename"
Cells(1, 7) = "Path"
Cells(1, 8) = "Track#"
Cells(1, 9) = "Duration"
Cells(1, 10) = "Size"
Range("1:1").Font.Bold = True
Range("1:1").Font.Italic = True
Range("1:1").Font.Name = "Consolas"
' Get files
FileName = Dir(currdir & "*.*", vbDirectory)
Do While Len(FileName) 0
If Left$(FileName, 1) "." Then 'Current dir
PathAndName = currdir & FileName
If (GetAttr(PathAndName) And vbDirectory) = vbDirectory Then
'store found directories
ReDim Preserve Dirs(0 To NumDirs) As Variant
Dirs(NumDirs) = PathAndName
NumDirs = NumDirs + 1
Else
If UCase(Right(FileName, 3)) = "MP3" Then
PathName = currdir 'path
FileName = FileName 'filename
TrackNum = FileInfo(currdir, FileName, 26) 'track
Duration = FileInfo(currdir, FileName, 27) 'duration
FileSize = Application.Round(FileLen(currdir & FileName) / 1024, 0) 'size
'Application.StatusBar = Row
If InStr(1, LCase(PathName), LCase("Best of"), vbTextCompare) Or InStr(1, LCase(PathName), LCase("Greatest"), vbTextCompare) Then
'Sht2Row = WorksheetFunction.CountA(Range("C:C")) + 1
Worksheets("Best_Greatest").Activate
Cells(Sht2Row, 2) = FileName
Cells(Sht2Row, 3) = PathName & FileName
Cells(Sht2Row, 7) = PathName
Cells(Sht2Row, 8) = TrackNum
Cells(Sht2Row, 9) = Duration
Cells(Sht2Row, 10) = FileSize
Sht2Row = Sht2Row + 1
Else
'Sht1Row = WorksheetFunction.CountA(Range("C:C")) + 1
Worksheets("Music_Library_Full").Activate
Cells(Sht1Row, 2) = FileName
Cells(Sht1Row, 3) = PathName & FileName
Cells(Sht1Row, 7) = PathName
Cells(Sht1Row, 8) = TrackNum
Cells(Sht1Row, 9) = Duration
Cells(Sht1Row, 10) = FileSize
Sht1Row = Sht1Row + 1
End If
End If
End If
End If
FileName = Dir()
Loop
' Process the found directories, recursively
For i = 0 To NumDirs - 1
RecursiveDir Dirs(i)
Next i
End Sub
Function FileInfo(path, FileName, item) As Variant
Dim objShell As IShellDispatch4
Dim objFolder As Folder3
Dim objFolderItem As FolderItem2
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(path)
Set objFolderItem = objFolder.ParseName(FileName)
FileInfo = objFolder.GetDetailsOf(objFolderItem, item)
Set objShell = Nothing
Set objFolder = Nothing
Set objFolderItem = Nothing
End Function
If anyone has any idea how to modify this so that pathnames containing a leading period as any part of the path can be returned, I'd be very glad to see it. I'd just rename those particular paths by removing the leading periods, but I'm afraid WMP will just one day put everything back the way it was (has happened before). Also, if you pick the actual folder in the BrowseForFolder API, that folder with the leading periods actually makes it into the sheet, but of course, only that folder.
Thanks
Look at this line in your code sample:
If Left$(FileName, 1) "." Then 'Current dir
Since the current directory is defined as a single '.' character, and this code only checks the initial character, it drops out before recursively examining it. Change the condition to check the length of the string as well as the initial character, e.g.
If (Left$(FileName, 1) = "." And FileName.Length = 1) Then 'Current dir
N.B. This code has not been tested; I hope it works for your use.
I was able to fix this by separating the test for root and subdirectory into separate IF statements, i.e.:
If filename <> "." Then
If filename <> ".." Then
*Code here*
End If
End If
Might be clunky, but it works.
The original If statement was:
If filename <> "." or filename <> ".." Then
This never worked. But then it occurred to me that maybe I needed to use a NAND statement. NAND = Not And. So I tried this:
if Not filename = "." And Not Filename = ".." then
This actually worked and seems to execute more rapidly than the earlier solution.
Option Explicit
' By John Walkenbach
' Maybe be distributed freely, but not sold
Sub GetAllFiles()
Dim Msg As String
Dim Directory
Msg = "Select the directory that contains the MP3 files. All subdirectories will be included."
Set Directory = Application.FileDialog(msoFileDialogFolderPicker)
With Directory
.Title = Msg
.AllowMultiSelect = False
.Show
If .SelectedItems.Count > 0 Then
Directory = .SelectedItems.item(1)
Else
Exit Sub
End If
End With
If Right(Directory, 1) <> "\" Then Directory = Directory & "\"
Worksheets("Sheet1").Activate
Cells.Clear
' Put column headings on active sheet
Cells(1, 1) = "Path"
Cells(1, 2) = "Filename"
Cells(1, 3) = "FullPath"
Cells(1, 4) = "Artist"
Cells(1, 5) = "Album"
Cells(1, 6) = "Title"
Cells(1, 7) = "Track#"
Cells(1, 8) = "Genre"
Cells(1, 9) = "Duration"
Cells(1, 10) = "Year"
Cells(1, 12) = "Size"
Range("1:1").Font.Bold = True
Call RecursiveDir(Directory)
End Sub
Public Sub RecursiveDir(ByVal currdir As String)
Dim Dirs() As Variant
Dim NumDirs As Long
Dim filename As String
Dim PathAndName As String
Dim i As Variant
Dim Row As Variant
' Make sure path ends in backslash
If Right(currdir, 1) <> "\" Then currdir = currdir & "\"
Application.ScreenUpdating = False
' Get files
filename = Dir(currdir & "*.*", vbDirectory)
Do While Len(filename) <> 0
DoEvents
If Not filename = "." And Not filename = ".." Then 'Current dir
PathAndName = currdir & filename
If (GetAttr(PathAndName) And vbDirectory) = vbDirectory Then
'store found directories
ReDim Preserve Dirs(0 To NumDirs) As Variant
Dirs(NumDirs) = PathAndName
NumDirs = NumDirs + 1
Else
If UCase(Right(filename, 3)) = "MP3" Then
Row = WorksheetFunction.CountA(Range("A:A")) + 1
Cells(Row, 1) = currdir 'path
Cells(Row, 2) = filename 'filename
Cells(Row, 3) = PathAndName
Cells(Row, 4) = FileInfo(currdir, filename, 20) 'artist
Cells(Row, 5) = FileInfo(currdir, filename, 14) 'album
Cells(Row, 6) = FileInfo(currdir, filename, 21) 'title
Cells(Row, 7) = FileInfo(currdir, filename, 26) 'track
Cells(Row, 8) = FileInfo(currdir, filename, 16) 'genre
Cells(Row, 9) = FileInfo(currdir, filename, 27) 'duration
Cells(Row, 10) = FileInfo(currdir, filename, 15) 'Year
Cells(Row, 11) = FileInfo(currdir, filename, 5)
Cells(Row, 12) = Application.Round(FileLen(currdir & filename) / 1024, 0) 'size
Application.StatusBar = Row
End If
End If
End If
filename = Dir()
Loop
' Process the found directories, recursively
For i = 0 To NumDirs - 1
RecursiveDir Dirs(i)
Next i
Application.StatusBar = False
End Sub
Function FileInfo(path, filename, item) As Variant
Dim objShell As IShellDispatch4
Dim objFolder As Folder3
Dim objFolderItem As FolderItem2
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(path)
Set objFolderItem = objFolder.ParseName(filename)
FileInfo = objFolder.GetDetailsOf(objFolderItem, item)
Set objShell = Nothing
Set objFolder = Nothing
Set objFolderItem = Nothing
End Function
Also, other fileinfo items: 27 = duration, 28 = bit rate, 26 = track number.

vb6 Compare times in list with current time

I'm making form where i need to enter the time's for each period like.
Start time - End time
Start time - End time
Start time - End time
Those record's could be saved in listbox as in my example. On another form i have 3 labels
CurrentTime, TimePassed, TimeLeft, and a Timer which ticks in interval 1second. So the time in timepassed ticking up, time left ticking down, and current time show correct time while application is opened.
In final it looks like this
Private Sub cmdAdd_Click()
Call addp
End Sub
Function addp(Optional ByVal t As String)
Dim s As String, e As String
If t = "" Then s = Trim(InputBox("Start time (hh:mm AM/PM):")) Else: s = Trim(Split(t, "-")(0))
If s = "" Or InStr(1, s, " AM") = 0 And InStr(1, s, " PM") = 0 Then Exit Function
If chk(s) = False Then Exit Function
If t = "" Then e = Trim(InputBox(s & "-?" & vbCrLf & "End time:")) Else: e = Trim(Split(t, "-")(1))
If e = "" Or InStr(1, e, " AM") = 0 And InStr(1, e, " PM") = 0 Then Exit Function
If e = s Then Exit Function
If chk(e) = False Then Exit Function
If Format$(Split(s, "-")(0), "hh:mm AM/PM") > Format$(Split(e, "-")(0), "hh:mm AM/PM") Then Exit Function
If lstPeriods.List(0) <> "" Then
If Format$(Split(lstPeriods.List(lstPeriods.ListCount - 1), "-")(1), "hh:mm AM/PM") > Format$(Split(s, "-")(0), "hh:mm AM/PM") Then Exit Function
End If
lstPeriods.AddItem lstPeriods.ListCount + 1 & ". " & s & "-" & e
If frmMain.lblPeriod.Caption = "" Then Call snd(s & "-" & e, lstPeriods.ListCount)
End Function
For check
Function chk(ByVal st As String) As Boolean
st = Replace$(Replace$(st, " AM", ""), " PM", "")
If UBound(Split(st, ":")) <> 1 Then Exit Function
For i = 0 To 1
If IsNumeric(Split(st, ":")(i)) = False Then Exit Function
If Len(Split(st, ":")(i)) <> 2 Then Exit Function
If Split(st, ":")(i) < 0 Then Exit Function
Next
If Split(st, ":")(0) > 12 Then Exit Function
If Split(st, ":")(1) > 59 Then Exit Function
chk = True
End Function
The solution i gave is the only solution which beginner as i I had. And i know it's confusing and very slow. There is no way this can be finished by using trim/split/format because it require for a lot of modification.
Searching for easier solution.
Sp i need to compare the current time on computer with the time person enetered in textbox/listbox how can i do that .
To Run this code you need to add 5 Controls to the Form1
lblSystemTime = Label Control
lblTimeLeft = Label Control
lblTimePassed = Label Control
lblPeriod = Label Control
tmrSystemTime = Timer Control
Dim Periods()
Private Sub Form_Load()
Periods = Array( _
"06:00 PM-07:00PM", _
"07:01 PM-08:00PM", _
"09:00 PM-10:00PM", _
"1AM-2AM" _
)
End Sub
Private Sub tmrSystemTime_Timer()
lblSystemTime.Caption = FormatDateTime(Now, vbLongTime)
Dim OnPeriod As Integer
OnPeriod = GetPeriod()
If OnPeriod < 0 Then
lblTimeLeft.Caption = vbNullString
lblTimePassed.Caption = vbNullString
lblPeriod.Caption = "Unknown Period"
Else
lblPeriod = CStr(OnPeriod + 1) & ". period"
lblTimeLeft.Caption = "Time Left: " & Format( _
DateAdd("s", _
DateDiff("s", _
CDate(lblSystemTime.Caption), _
CDate(Split(Periods(OnPeriod), "-")(1))), _
CDate("0") _
), _
"nn:ss" _
)
lblTimePassed.Caption = "Time Passed: " & Format( _
DateAdd("s", _
DateDiff("s", _
CDate(Split(Periods(OnPeriod), "-")(1)), _
CDate(lblSystemTime.Caption)), _
CDate("0") _
), _
"nn:ss" _
)
End If
End Sub
Private Function GetPeriod() As Integer
Dim ICount As Integer
For Each Pr In Periods
If CDate(Split(Pr, "-")(0)) <= CDate(lblSystemTime.Caption) And _
CDate(Split(Pr, "-")(1)) >= CDate(lblSystemTime.Caption) Then
GetPeriod = ICount
Exit Function
End If
ICount = ICount + 1
Next
GetPeriod = -1
End Function
Here is something which may help:
Private Sub TimeCheck(byval int_TimeNow as Integer)
dim intTimeThen as string 'set a variable to compare for the THEN time
dim intTimeNow as string 'set a variable to compare for the NOW time
dim intDiff as string ' set a variable for the difference in time
intTimeNow = int_TimeNow 'just to ensure we don't mess with any data
intTimeThen = val(txtTimeThen.text) 'get the numeric value of the time, the system will
'convert it from a string to the value here.
intDiff = intTimeThen - intTimeNow 'Do the math
lstTimeEvents.additem timevalue(intDiff) 'write it to a listbox
End Sub
I realize this is not the coding convention you are using, but it should demonstrate what you are looking for to some degree.

Resources