ListView Column Width

Rex2024

New Member
Joined
Nov 17, 2022
Messages
32
Office Version
  1. 365
Platform
  1. Windows
I would like to either manually set the width for each column in my listview. In addition, I'd like to be able to word wrap certain columns. How can I do this?

VBA Code:
Option Explicit

Private Sub Add_Click()

End Sub

Private Sub UserForm_Activate()

With Me.LV1
    .View = lvwReport
    .Gridlines = True
    .HideColumnHeaders = False
End With

Call LoadListView

End Sub

Private Sub LoadListView()

Dim wksSource As Worksheet
Dim rngData As Range
Dim RngCell As Range
Dim LstItem As ListItem
Dim RowCount As Long
Dim ColCount As Long
Dim i As Long
Dim j As Long

Set wksSource = Worksheets("FormDataTesting")
Set rngData = wksSource.Range("A1").CurrentRegion

For Each RngCell In rngData.Rows(1).Cells
    Me.LV1.ColumnHeaders.Add Text:=RngCell.Value, Width:=90
Next RngCell

RowCount = rngData.Rows.Count

ColCount = rngData.Columns.Count

For i = 2 To RowCount
    Set LstItem = Me.LV1.ListItems.Add(Text:=rngData(i, 1).Value)
    For j = 2 To ColCount
        LstItem.ListSubItems.Add Text:=rngData(i, j).Value
    Next j
Next i

End Sub
 

Excel Facts

Show numbers in thousands?
Use a custom number format of #,##0,K. Each comma after the final 0 will divide the displayed number by another thousand
Sorry! Should have posted that. I never did wrap text, but this is how I got columns to the sizes I wanted.

VBA Code:
    With EventLog.ListView1
    
'Build column headers
    .ListItems.Clear
    .ColumnHeaders.Clear
    .FullRowSelect = True
    .ColumnHeaders.Add , , "Event ID", 0
    .ColumnHeaders.Add , , "EmpNum", 50
    .ColumnHeaders.Add , , "First Name", 80
    .ColumnHeaders.Add , , "Last Name", 80
    .ColumnHeaders.Add , , "Subject", 60
    .ColumnHeaders.Add , , "Subject Detail", 60
    .ColumnHeaders.Add , , "Details", 250

'To speed things up my listview uses an array

    Set LVRange = ws.Range("A1").CurrentRegion
    LVArray = LVRange
    
    X = 1
    
    On Error Resume Next
    
    For P = UBound(LVArray) To 0 Step -1
        If X > 500 Then 'I only wanted 500 items. This counts the latest and then goes in reverse
            GoTo Count500
        Else
        End If
        
    Set el = .ListItems.Add(, , LVArray(P, 1)) 'Event ID
    el.ListSubItems.Add , , LVArray(P, 2) 'EmpNum
    el.ListSubItems.Add , , LVArray(P, 4) 'Last Name
    el.ListSubItems.Add , , LVArray(P, 3) 'First Name
    el.ListSubItems.Add , , LVArray(P, 12) 'Subject
    el.ListSubItems.Add , , LVArray(P, 13) 'Subject Detail
    el.ListSubItems.Add , , LVArray(P, 5) 'Details

    X = X + 1
    
    Next P

End With
 
Upvote 0
Yes, this is good when loading one at a time. But loading a ListView from an Excel Table using a For Loop doesn't allow for that. It would be good to loop through each column after the fact and set widths based on widest ListItem content.

I see several instances of this in VB|.Net|C# but can not find an example for VBA. Surely there is one.

Thanks for the comeback
doco
 
Upvote 0
Yes, this is good when loading one at a time. But loading a ListView from an Excel Table using a For Loop doesn't allow for that. It would be good to loop through each column after the fact and set widths based on widest ListItem content.

I see several instances of this in VB|.Net|C# but can not find an example for VBA. Surely there is one.

Thanks for the comeback
doco
Yeah, I never figured it out and ended up just going this route. Sorry I wasn't more help for your need!
 
Upvote 0
I don't have the ListView control installed since I am on 64bit excel so I can't carry out a test but, I suspect that since the LisView has a window handle ,sending the SET_COLUMN_WIDTH message along with AUTOSIZE_USEHEADER lParam should work

VBA Code:
Option Explicit

#If VBA7 Then
    Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
#Else
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
#End If

Public Sub AutosizeColumns(ByVal TargetListView As ListView)
    Const SET_COLUMN_WIDTH    As Long = 4126&
    Const AUTOSIZE_USEHEADER  As Long = -2&
    Dim lColumn As Long
    For lColumn = 0& To TargetListView.ColumnHeaders.Count - 1&
        Call SendMessage(TargetListView.hwnd, SET_COLUMN_WIDTH, lColumn, ByVal AUTOSIZE_USEHEADER)
    Next lColumn
End Sub

The just call it like this:
VBA Code:
Call AutosizeColumns(ListView1)
 
Upvote 0

Forum statistics

Threads
1,223,886
Messages
6,175,193
Members
452,616
Latest member
intern444

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top