Search code examples
excelvba

Copy range of cells from current worksheet to a text file while deleting previous text file


The VBA code below was modified with the help of user taller.

The code:

  1. Copies a range of cells from my current worksheet

  2. Creates a text file with name "Unsuppression_dd.MM_01", where dd.MM is the current date and month, and 01 is the version number 1.

  3. Pastes the cell value to the text file and closes it.

  4. When the code is run for a second time, it copies the cell values and then creates a text file with incremented version ("Unsuppression_dd.MM_02") and pastes to that.
    It also deletes the previous version text file ("Unsuppression_dd.MM_01")

  5. When the code is run for a third time, it copies the cell values and then creates a text file with incremented version ("Unsuppression_dd.MM_03") and pastes to that.
    It also deletes the previous version text file ("Unsuppression_dd.MM_02").

Example:
Suppose I execute the code five times today, the last txt file created is "Unsuppression_20.11_05" which is the only text file present in my folder Path.

Sub StackOverfolow_UpdatetextfilewithVersion()
    ' Define folder path
    Dim folderPath As String
    folderPath = "C:\Users\kuldeep\Desktop\SIM_macro\New exp\Unsuppression_" & Format(Date, "dd.MM") & "_"
    
    ' Define range to copy
    Dim copyRange As Range
    Set copyRange = ThisWorkbook.Sheets("Sheet1").Range("H2:H8")
    
    ' Copy values to array
    Dim valuesArray As Variant
    valuesArray = copyRange.Value
    
    Dim versionNumber As Integer, aTxt
    Dim fName As String, baseFolder As String
    baseFolder = "C:\Users\kbkmth\Desktop\SIM_macro\New exp\"
    versionNumber = 1
    
    ' Check for existing versions and delete them
    fName = Dir(folderPath & "*.txt")
    If Len(fName) > 0 Then
        ' Delete the previous version with a delay
        Application.Wait Now + TimeValue("00:00:01") ' 1 second delay
        Kill baseFolder & fName
        aTxt = Split(fName, "_")
        ' Increment version number
        versionNumber = CInt(Left(aTxt(UBound(aTxt)), 2)) + 1
    End If
    
    ' Open file for writing with the correct version number
    Dim fileNumber As Integer
    fileNumber = FreeFile
    Open folderPath & Format(versionNumber, "00") & ".txt" For Output As fileNumber
    
    ' Write values to file
    For i = 1 To UBound(valuesArray, 1)
        Print #fileNumber, valuesArray(i, 1)
    Next i
    
    ' Close file
    Close fileNumber
End Sub

I'm facing one issue.
When I run the code after changing my date in my Windows system settings, the code creates version "01" with the new date and retains the last created version from the prior day.

Is it possible to delete the prior day's text file?

Example of the issue:
Suppose I execute the code five times today, the last text file created is "Unsuppression_20.11_05" which is the only text file present in my folder Path.
When I run the code after changing the date to November 21st (in my Windows system settings), a new text document named "Unsuppression_21.11_01" is created.

My folder Path still has the text file "Unsuppression_20.11_05" (last created version from the previous day).


Solution

  • Pattern match the Unsuppression_dd.MM_00 with a Regular Expression to extract the dd.MM and compare with current date. Increment version for those with current date only and fill a collection with file names to delete later. I have put the code in a function to keep your existing code cleaner.

    Option Explicit
    
    Sub test()
    
        Const basefolder = "C:\Users\kbkmth\Desktop\SIM_macro\New exp\"
        
        ' determine filename
        Dim fnew As String
        fnew = getNextVersion(basefolder, "Unsuppression_")
        If fnew = "" Then
             MsgBox "Error in getNextVersion()"
             Exit Sub
        End If
       
        ' create file
        Dim fileNumber As Integer
        fileNumber = FreeFile
        Open basefolder & fnew For Output As fileNumber
        ' write text
        Close fileNumber
        
    End Sub
    
    Function getNextVersion(basefolder, fname) As String
    
        Dim regex As Object, m As Object, sm As Object
        Dim dt As Date, today As Date, yr As Long
        Dim f As String, fnew As String, verno As Long
        Dim colDelete As Collection
        Set colDelete = New Collection
        
        ' pattern match filenames _mm.dd_nn.txt
        Set regex = CreateObject("vbscript.regexp")
        With regex
           .Global = False
           .MultiLine = False
           .IgnoreCase = True
           .Pattern = fname & "(\d\d)\.(\d\d)_(\d\d).txt" ' pattern
        End With
        
        ' initial version
        verno = 1
        
        ' current date
        today = Date
        yr = Year(today)
        
        ' scan folder for files
        f = Dir(basefolder & "*.txt")
        Do While Len(f) > 0
            ' match filenam
            Set m = regex.Execute(f)
            If m.Count = 1 Then
                ' extract dd and mm
                Set sm = m(0).submatches
                dt = DateSerial(yr, sm(1), sm(0))
                'is date today
                If dt = today Then
                    ' check if a version number exists
                    If sm(2) >= verno Then verno = sm(2) + 1
                End If
                
                ' add to collection to delete later
                colDelete.Add f
                'Debug.Print verno, sm(0), sm(1), sm(2)
            End If
            f = Dir ' next file
        Loop
        
        ' build new filename
        fnew = fname & Format(today, "dd.mm") & Format(verno, "_00") & ".txt"
        
        ' delete old file(s)
        Dim msg As String, n As Long
        For n = 1 To colDelete.Count
            Kill basefolder & colDelete(n)
            msg = msg & vbLf & colDelete(n)
        Next
        MsgBox "New file" & vbLf & fnew & vbLf & "Files deleted" & msg
    
        getNextVersion = fnew
    
    End Function