Home > Net >  copy array list in to email body
copy array list in to email body

Time:09-09

i am trying display the result of an array into a body of an email but I get an error subscript out of range

I am not yet well understood in manipulating arrays so Im having trouble solving the error

could anyone help me?

Dim lRow As Long
Dim sBody, y
Dim location_sheet As String
Dim sq(), ar, x As Long, j As Long, jj As Long

y = 2
lRow = Cells(Rows.Count, 4).End(xlUp).Row

For Each c In Worksheets("Addresses").Range("D2:D" & lRow).Cells

    location_sheet = c.Value
    ar = Sheets(location_sheet).UsedRange
    
    For j = 1 To UBound(ar)
         For jj = 1 To UBound(ar, 2)
           If ar(j, jj) <> "" Then
               ReDim Preserve sq(x)
               sq(x) = ar(j, jj)
              x = x   1
             End If
         Next
     Next
    
    sBody = "Hi,"
        Do While y <= x
          sBody = sBody & vbNewLine & sq(y) ' subscript out of range sq(y)
          y = y   1
        Loop
    
    With CreateObject("outlook.application").createitem(0)
       .To = c.Offset(0, -1).Value
       .Subject = c.Offset(0, -3).Value & " " & c.Offset(0, -2).Value & "-" & c.Value
       .body = sBody
       '.Attachments.Add
       .display '.send
     End With
     
Next

CodePudding user response:

Copy Array to Email Body

Option Explicit

Sub LoopAndSendMail()
    
    ' Reference the workbook ('wb').
    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    
    ' Write the addresses data to a 2D one-based array ('aData').
    Dim aws As Worksheet: Set aws = wb.Worksheets("Addresses")
    Dim alCell As Range: Set alCell = aws.Cells(aws.Rows.Count, "D").End(xlUp)
    Dim arg As Range: Set arg = aws.Range("A2", alCell)
    Dim arCount As Long: arCount = arg.Rows.Count
    Dim aData() As Variant: aData = arg.Value
    
    ' Declare additional variables.
    
    ' Addresses
    Dim ar As Long
    
    ' Body (Location)
    Dim bArr() As String
    Dim bnCount As Long
    Dim bn As Long
    
    ' Location
    Dim lws As Worksheet
    Dim lName As String
    Dim lrg As Range
    Dim lData() As Variant
    Dim lrCount As Long
    Dim lcCount As Long
    Dim lr As Long
    Dim lc As Long
    Dim lString As String
    
    ' Loop through the rows of the addresses data...
    For ar = 1 To arCount
        
        lName = CStr(aData(ar, 4))
        
        ' Attempt to reference the location worksheet ('lws').
        On Error Resume Next
            Set lws = wb.Worksheets(lName)
        On Error GoTo 0
        
        If Not lws Is Nothing Then ' the location worksheet exists
            
            ' Reference the location range ('lrg') (one row of headers).
            Set lrg = lws.UsedRange
            Set lws = Nothing ' reset the variable to reuse in next iteration
            
            lrCount = lrg.Rows.Count
            
            If lrCount > 1 Then ' the location range has more than one row
            
                lcCount = lrg.Columns.Count
                bnCount = (lrCount - 1) * lcCount ' exclude headers (- 1)
                
                ' Write the values from the location range
                ' to a 2D-one based array ('lData').
                lData = lrg.Value
                ' The previous line is so simple because we have made sure
                ' that the range contains more than one row but we have
                ' to make sure that the loop starts with row 2 (see below).
                
                ' Note that the use of the body array can be replaced with
                ' writing to a string (which is possibly even more efficient).
                ' But let's say we are practicing using arrays.
                
                ' Resize the body array to the maximum possible size.
                ReDim bArr(1 To bnCount)
                
                ' Write non-blanks from the location array to the body array.
                For lr = 2 To lrCount ' skip headers (2)
                    For lc = 1 To lcCount
                        lString = CStr(lData(lr, lc))
                        If Len(lString) > 0 Then ' is not blank
                            bn = bn   1 ' next element
                            bArr(bn) = lString ' write
                        'Else ' is blank; do nothing
                        End If
                    Next lc
                Next lr
                
                If bn > 0 Then ' non-blanks found
                    
                    ' Correct the size of the body array.
                    If bn < bnCount Then ' blanks found
                        ReDim Preserve bArr(1 To bn) ' resize (shrink)
                    'Else ' no blanks found; do nothing i.e. the size is correct
                    End If
                    
                    bn = 0 ' reset the variable to reuse in next iteration
                            
                    ' Email
                    With CreateObject("Outlook.Application").CreateItem(0)
                       .To = CStr(aData(ar, 3))
                       .Subject = CStr(aData(ar, 1)) & " " _
                           & CStr(aData(ar, 2)) _
                           & "-" & lName ' lName = CStr(aData(ar, 4))
                       .Body = "Hi," & vbLf & vbLf & Join(bArr, vbLf)
                       '.Attachments.Add
                       .Display '.Send
                    End With
                    
                'Else ' no non-blanks found; do nothing
                End If
            
            'Else ' the loc. range has only one row or the worksheet is empty
            End If
            
        'Else ' the location worksheet doesn't exist; do nothing
        End If
        
    Next ar
    
End Sub

CodePudding user response:

i figured it out in the in the do while loop should only be x<y not x<=y and cleared the body,y,x, redim sq(x) since it will be reused inside the for loop

Dim sBody, y
Dim location_sheet As String
Dim sq(), ar, x As Long, j As Long, jj As Long

y = 2
lRow = Cells(Rows.Count, 4).End(xlUp).Row

For Each c In Worksheets("Addresses").Range("D2:D" & lRow).Cells

    sBody = "" 'clear coz will be reused inside for loop
    y = 0 'clear coz will be reused inside for loop
    x = 0 'clear coz will be reused inside for loop
    ReDim sq(x) 'clear coz will be reused inside for loop

    location_sheet = c.Value
    ar = Sheets(location_sheet).UsedRange
    
    For j = 1 To UBound(ar)
         For jj = 1 To UBound(ar, 2)
           If ar(j, jj) <> "" Then
               ReDim Preserve sq(x)
               sq(x) = ar(j, jj)
              x = x   1
             End If
         Next
     Next
    
    sBody = "Hi,"
        Do While y < x
          sBody = sBody & vbNewLine & sq(y)
          y = y   1
        Loop
    
    With CreateObject("outlook.application").createitem(0)
       .To = c.Offset(0, -1).Value
       .Subject = c.Offset(0, -3).Value & " " & c.Offset(0, -2).Value & "-" & c.Value
       .body = sBody
       '.Attachments.Add
       .display '.send
     End With
     
Next
  • Related