Home > Net >  Is it possible to fill cells in a range with "x" if the number of filled cells in that col
Is it possible to fill cells in a range with "x" if the number of filled cells in that col

Time:07-25

In a sheet of my workbook I have range C8:C104 filled with values from another sheet of my workbook. These number of values can vary from 2 to 96 with no blank cells in between.

Before copying these values to a txt-file I need to auto fill blank cells in this column until the number of non blank cells in the range can be divided by 4.

Example:

C8:C12 contain data => no cells need to be auto filled

C8:C10 contain data => Cells C11 and C12 need to be filled with the text "x" (the rest of the cells in the range stay blank)

Normally Google is my best friend in situations like this, but unfortunately I could not find any Q&A similar to this. I got the part running to copy the cells and sending them as a txt.file by outlook mail, but have no clue how to get the auto fill part up and running yet. Is there anyone who can help me get started, am not very experienced and a bit rusty with my VBA skills?

CodePudding user response:

Return a Column in a String Conditionally

  • Adjust the values in the constants section.
  • Reference the worksheet more safely.
Option Explicit

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      Tests the 'StrFilledColumnRange' function.
' Calls:        StrFilledColumnRange, TextString.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub StrFilledColumnRangeTEST()
    
    ' Define constants.
    Const FilePath As String = "C:\Test\Test.txt"
    Const crgAddress As String = "C8:C104"
    Const FillString As String = "x"
    Const ModNonBlank As Long = 4
    Const HasHeader As Boolean = True

    ' Reference the worksheet ('ws').
    Dim ws As Worksheet: Set ws = ActiveSheet ' improve!
    
    ' Reference the (one-column) range ('crg').
    Dim crg As Range: Set crg = ws.Range(crgAddress)
    
    ' Using the function, return the required values in a string ('rString').
    Dim rString As String
    rString = StrFilledColumnRange(crg, FillString, ModNonBlank, True)
    
    ' Check if the string is empty.
    If Len(rString) = 0 Then
        MsgBox "The resulting string is empty.", vbExclamation
        Exit Sub
    End If

    ' Display the result.
    Debug.Print rString
    'MsgBox rString, vbInformation

    ' Write the string to a text file.
    'TextString FilePath, rString

End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      From a given one-column range, returns a string that...
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function StrFilledColumnRange( _
    ByVal ColumnRange As Range, _
    ByVal FillString As String, _
    Optional ByVal ModNonBlank As Long = 1, _
    Optional ByVal HasHeader As Boolean = False) _
As String
    Const ProcName As String = "StrFilledColumnRange"
    On Error GoTo ClearError
    
    ' Reference the first cell ('fCell') of the range.
    Dim fCell As Range: Set fCell = ColumnRange.Cells(1)
    
    ' Reference the column data range ('cdrg')(no headers).
    Dim hrOffset As Long
    If HasHeader Then hrOffset = 1
    Dim cdrg As Range: Set cdrg = ColumnRange _
        .Resize(ColumnRange.Rows.Count - hrOffset).Offset(hrOffset)
    
    ' Make sure that all rows and columns are visible, or the following
    ' use of the Find method will fail.
    ' Reference the bottom-most non-blank cell ('lCell')
    ' of the column data range ('xlValues' - non-blanks).
    Dim lCell As Range: Set lCell = cdrg.Find("*", , xlValues, , , xlPrevious)
    If lCell Is Nothing Then
        MsgBox "No data in '" & cdrg.Address(0, 0) & "'.", vbCritical
        Exit Function
    End If
    
    ' Retrieve the current number of rows ('crCount') of the column data range.
    Dim crCount As Long: crCount = lCell.Row - fCell.Row - hrOffset   1
    
    ' Calculate the remainder ('Remainder'), the number of how many
    ' fill strings to be 'appended'.
    Dim Remainder As Long: Remainder = crCount Mod ModNonBlank
    If Remainder > 0 Then Remainder = ModNonBlank - Remainder
    
    ' Write the source number of rows to a variable ('srCount').
    Dim srCount As Long: srCount = ColumnRange.Rows.Count
    
    ' Calculate the destination number of rows ('drCount')
    ' and correct 'Remainder'.
    Dim drCount As Long: drCount = hrOffset   crCount   Remainder
    If drCount > srCount Then
        Remainder = Remainder   srCount - drCount
        drCount = srCount
    End If
    
    ' Declare a variable for the resulting string ('rString').
    Dim rString As String
    
    If drCount = 1 Then ' one cell only; unlikely yet theoretically possible
        rString = ColumnRange.Value
    Else ' multiple cells
        ' Reference the last (offsetted) cell.
        Set lCell = lCell.Offset(Remainder)
        ' Reference the range ('crg').
        Dim crg As Range: Set crg = ColumnRange.Worksheet.Range(fCell, lCell)
        ' Write the values from the range to a 2D one-based array ('cData').
        Dim cData() As Variant: cData = crg.Value
        ' Write the fill string(s) to the array.
        Dim dr As Long ' Current Destination Row
        For dr = drCount To drCount - Remainder   1 Step -1
            cData(dr, 1) = FillString
        Next dr
        ' Write the values from the array to the resulting string.
        rString = cData(1, 1)
        For dr = 2 To drCount
            rString = rString & vbLf & cData(dr, 1)
        Next dr
    End If
    
    ' Return the string as the result of the function.
    StrFilledColumnRange = rString
    
ProcExit:
    Exit Function
ClearError:
    Debug.Print "'" & ProcName & "' Run-time error '" _
        & Err.Number & "':" & vbLf & "    " & Err.Description
    Resume ProcExit
End Function

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      Writes a string to a file.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub TextString( _
        ByVal FilePath As String, _
        ByVal WriteString As String)
    Const ProcName As String = "TextString"
    On Error GoTo ClearError
    
    Dim TextFile As Long: TextFile = FreeFile
    
    Open FilePath For Output Access Write As #TextFile
        Print #TextFile, WriteString
    Close TextFile
    
ProcExit:
    Exit Sub
ClearError:
    Debug.Print "'" & ProcName & "' Run-time error '" _
        & Err.Number & "':" & vbLf & "    " & Err.Description
    Resume ProcExit
End Sub

CodePudding user response:

The following will pad the cells with x until there are a multiple of 4 cells populated:

Sub pad_to_mod_4()

    Dim myrange As Range
    Dim ws As Worksheet

    padding = "x"
    
    Set ws = ActiveSheet                'set this to your worksheet
    Set myrange = ws.Range("C8:C104")
    
    Do Until myrange.Cells.SpecialCells(xlCellTypeConstants).Count Mod 4 = 0
        myrange(myrange.Count).End(xlUp).Offset(1, 0).Value = padding
    Loop
    
End Sub
  • Related