1
votes

I'm receiving the following error when I run my .vbs:

Script: C:\Users\Me\Desktop\delete.vbs
Line: 21
Char: 1
Error: Invalid procedure call or argument
Code: 800A0005
Source: Microsoft VBScript runtime error

Here is the code.

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder("C:\Users\PLEX\Downloads\Completed\")

intFolderSize = Int(((objFolder.Size / 1024) / 1024) / 1024)

Do While intFolderSize >= 79
  strOldestFile = ""
  dtmOldestDate = Now

  Set colFiles = objFolder.Files

  For Each objFile in colFiles
    strFile = objFile.Path
    dtmFileDate = objFile.DateCreated
    If dtmFileDate < dtmOldestDate Then
      dtmOldestDate = dtmFileDate
      strOldestFile = strFile
    End If
  Next

  objFSO.DeleteFile(strOldestFile)

  intFolderSize = Int(((objFolder.Size / 1024) / 1024) / 1024)
Loop

The error is on the line objFSO.DeleteFile(strOldestFile).

Could anyone tell me why, and how to fix it?

1

1 Answers

1
votes

strOldestFile seems to be a string of zero length as initialized in strOldestFile = "" statement.

Size Property

For files, returns the size, in bytes, of the specified file. For folders, returns the size, in bytes, of all files and subfolders contained in the folder.

object.Size

The object is always a File or Folder object

You could either iterate files in subfolders or end the loop as follows:

If strOldestFile = "" Then
    Wscript.Echo "No file to delete"
    intFolderSize = 0                 ' end loop
                                      ' or recurse to subfolders
                                      ' or choose another strategy at all
Else
    objFSO.DeleteFile(strOldestFile)
    intFolderSize = Int(((objFolder.Size / 1024) / 1024) / 1024)
End If

Next script should work:

option explicit
On Error GoTo 0

Dim strResult: strResult = Wscript.ScriptName
Dim objFSO, strOldestFile, dtmOldestDate, strFolder, oFolder, intFolderSize
Set objFSO = CreateObject("Scripting.FileSystemObject")
    dtmOldestDate = Now
    strFolder = "C:\Users\PLEX\Downloads\Completed\"
    strOldestFile = "" 
Set oFolder = objFSO.GetFolder( strFolder)

intFolderSize = Int(((oFolder.Size / 1024) / 1024) / 1024)

'Do While intFolderSize >= 79
  strOldestFile = ""
  dtmOldestDate = Now

  FindOldestFile oFolder

  'objFSO.DeleteFile(strOldestFile)
  strResult = strResult & vbNewLine & dtmOldestDate & vbTab & strOldestFile 

  intFolderSize = Int(((oFolder.Size / 1024) / 1024) / 1024)

'Loop

Wscript.Echo strResult
Wscript.Quit

Sub FindOldestFile( objFolder)
  Dim objFile, colFiles, colFolders, strFile, dtmFileDate
  ' find oldest file
  Set colFiles = objFolder.Files
  For Each objFile in colFiles
    strFile = objFile.Path
    dtmFileDate = objFile.DateCreated
    If dtmFileDate < dtmOldestDate Then
      dtmOldestDate = dtmFileDate
      strOldestFile = strFile
    End If
  Next
  ' recurse subfolders
  Set colFolders = objFolder.SubFolders
  For Each objFile in colFolders
    FindOldestFile objFile
  Next
End Sub

Note that there are some commands commented up for debugging purposes (Do While, Loop, DeleteFile); the oldest file is echoed instead.

Above code is not optimized in any sense; maybe better would be, to avoid rereading filesystem attributes repeatedly:

  • create an array of file paths and dates and sizes,
  • sort order such array by dates, and then
  • delete files summing deleted size…

Edit: full code with basic error handling

option explicit
On Error GoTo 0

Dim strResult: strResult = Wscript.ScriptName
Dim objFSO, dtmOldestDate, strFolder, oFolder, intFolderSize
Dim ii, intSizeToDele, arrAux, arrFilesSorted, arrFilesUnSort()
    ii = -1
    strFolder = "d:\test"                     ' "C:\Users\PLEX\Downloads\Completed\"
    dtmOldestDate = Now

  Set objFSO  = CreateObject("Scripting.FileSystemObject")
  Set oFolder = objFSO.GetFolder( strFolder)

  FindAllFiles oFolder
  arrFilesSorted = BubbleSort(arrFilesUnSort,"")
  intFolderSize  = oFolder.Size
  intSizeToDele  = Int(intFolderSize / 50)   ' redefine to match your need
  strResult = strResult & vbTab & ii _
    & vbTab & intSizeToDele & vbTab & intFolderSize
  For ii = 0 To UBound( arrFilesSorted)
    arrAux = Split( arrFilesSorted( ii), "|")
    strResult = strResult & vbNewLine & ii _
      & vbTab & arrAux(0) _
      & vbTab & arrAux(1) _
      & vbTab & arrAux(2)
    On Error Resume Next                      ' basic error handling - start
      ''''' objFSO.DeleteFile(arrAux(2))      ' uncomment no sooner than debugged
      If Err.Number = 0 Then 
      Else
        strResult = strResult & vbNewLine & ii _
          & vbTab & CStr(Err.Number) & " (0x" & Hex(Err.Number) & ") " & Err.Description
      End If
    On Error GoTo 0                           ' basic error handling - end
    intSizeToDele = intSizeToDele - arrAux(1)
    If intSizeToDele <= 0 Then Exit For  
  Next
  strResult = strResult & vbNewLine & ii _
    & vbTab & intSizeToDele & vbTab & intFolderSize

Wscript.Echo strResult
Wscript.Quit

Sub FindAllFiles( objFolder)
  Dim objFile, colFiles, colFolders
  ' find all files
  Set colFiles = objFolder.Files
  For Each objFile in colFiles
    ii = ii + 1
    ReDim Preserve arrFilesUnSort(ii)
    arrFilesUnSort(ii) = timeStamp( objFile.DateCreated) & "|" & objFile.Size & "|" & objFile.Path
  Next
  ' recurse subfolders
  Set colFolders = objFolder.SubFolders
  For Each objFile in colFolders
    FindAllFiles objFile
  Next
End Sub

Function BubbleSort(ByVal arrData,strSort)
'Based on http://vbscripter.blogspot.cz/2008/03/q-how-do-i-sort-data-in-array.html
'Input: arrData = Array of data. Text or numbers.
'Input: strSort = Sort direction (ASC or ascending or DESC for descending)
'Output: Array
'
  Dim i, j, TempValue
  If Not Trim(UCase(strSort)) = "DESC" Then strSort = "ASC"

  If strSort = "ASC" Then
      For i = 0 to UBound(arrData)
          For j = 0 to UBound(arrData) - 1
              If  arrData(j)   > arrData(j+1) Then
                  TempValue    = arrData(j+1)
                  arrData(j+1) = arrData(j)
                  arrData(j)   = TempValue
              End If
          Next
      Next
  Else
      For i = 0 to UBound(arrData)
          For j = 0 to UBound(arrData) - 1
              If  arrData(j)   < arrData(j+1) Then
                  TempValue    = arrData(j+1)
                  arrData(j+1) = arrData(j)
                  arrData(j)   = TempValue
              End If        
          Next
      Next
  End If 

  BubbleSort = arrData
End Function

Function timeStamp( tt)
'Input:   tt = date (a Variant of subtype Date)
'Output:  sortable, fixed-length string: date formatted as yyyymmddHHMMSS
  timeStamp = CStr( Year (tt) & _
    Right("0" & Month (tt),2) & _
    Right("0" & Day   (tt),2) & _  
    Right("0" & Hour  (tt),2) & _
    Right("0" & Minute(tt),2) & _    
    Right("0" & Second(tt),2))
End Function