Как добавить заголовки в список из нескольких столбцов в пользовательской форме Excel с помощью VBA - PullRequest
10 голосов
/ 18 марта 2009

Можно ли настроить заголовки в многоколоночном списке без использования диапазона листа в качестве источника?

В следующем примере используется массив вариантов, который назначен свойству list из списка, заголовки отображаются пустыми.

Sub testMultiColumnLb()
    ReDim arr(1 To 3, 1 To 2)

    arr(1, 1) = "1"
    arr(1, 2) = "One"
    arr(2, 1) = "2"
    arr(2, 2) = "Two"
    arr(3, 1) = "3"
    arr(3, 2) = "Three"


    With ufTestUserForm.lbTest
        .Clear
        .ColumnCount = 2
        .List = arr
    End With

    ufTestUserForm.Show 1
End Sub

Ответы [ 12 ]

17 голосов
/ 18 марта 2009

Нет. Я создаю надписи над списком, чтобы они служили заголовками. Вы можете подумать, что менять ярлыки каждый раз, когда меняется ваш список, - королевская боль. Вы были бы правы - это боль. Это сложно настроить в первый раз, гораздо меньше изменений. Но я не нашел лучшего способа.

6 голосов
/ 06 марта 2014

Я смотрел на эту проблему только сейчас и нашел это решение. Если ваш RowSource указывает на диапазон ячеек, заголовки столбцов в многоколоночном списке берутся из ячеек непосредственно над RowSource.

Используя приведенный здесь пример, внутри списка, слова Символ и Имя отображаются в качестве заголовков заголовков. Когда я изменил слово Name в ячейке AB1, а затем снова открыл форму в VBE, заголовки столбцов изменились.

Screenshot displaying a named range and the column headings outside the range.

Пример получен из рабочей книги VBA For Modelers С. Кристиана Олбрайта, и я пытался выяснить, как он получил заголовки столбцов в своем списке:)

5 голосов
/ 13 апреля 2017

Вот мой подход к решению проблемы:

Это решение требует, чтобы вы добавили второй элемент ListBox и поместили его над первым.

Как это:

Add an additional ListBox

Затем вызывается функция CreateListBoxHeader, чтобы сделать выравнивание правильным и добавить элементы заголовка.

Результат:

Call the function CreateListBoxHeader

Код:

  Public Sub CreateListBoxHeader(body As MSForms.ListBox, header As MSForms.ListBox, arrHeaders)
            ' make column count match
            header.ColumnCount = body.ColumnCount
            header.ColumnWidths = body.ColumnWidths

        ' add header elements
        header.Clear
        header.AddItem
        Dim i As Integer
        For i = 0 To UBound(arrHeaders)
            header.List(0, i) = arrHeaders(i)
        Next i

        ' make it pretty
        body.ZOrder (1)
        header.ZOrder (0)
        header.SpecialEffect = fmSpecialEffectFlat
        header.BackColor = RGB(200, 200, 200)
        header.Height = 10

        ' align header to body (should be done last!)
        header.Width = body.Width
        header.Left = body.Left
        header.Top = body.Top - (header.Height - 1)
End Sub

Использование:

Private Sub UserForm_Activate()
    Call CreateListBoxHeader(Me.listBox_Body, Me.listBox_Header, Array("Header 1", "Header 2"))
End Sub
5 голосов
/ 18 марта 2009

Простой ответ: нет.

В прошлом я загружал заголовки в строку 0, затем устанавливал ListIndex на 0 при отображении формы. Затем это выделяет «заголовки» синим цветом, создавая видимость заголовка. Кнопки действий формы игнорируются, если ListIndex остается на нуле, поэтому эти значения никогда не могут быть выбраны.

Конечно, как только выбран другой элемент списка, заголовок теряет фокус, но к этому времени их работа завершена.

Подобные действия также позволяют вам иметь заголовки с горизонтальной прокруткой, что трудно / невозможно сделать с отдельными метками, которые плавают над списком. Обратная сторона в том, что заголовки не остаются видимыми, если список должен прокручиваться вертикально.

По сути, это компромисс, который работает в ситуациях, в которых я был.

4 голосов
/ 13 декабря 2016

Существует очень простое решение для отображения заголовков в верхней части списка из нескольких столбцов. Просто измените значение свойства на «true» для «столбцов», которое по умолчанию равно false.

После этого Просто упомяните диапазон данных в свойстве "rowources", исключая заголовок из диапазона данных, и заголовок должен находиться в первой верхней строке диапазона данных, затем он автоматически выберет заголовок, и ваш заголовок будет заморожен.

если предположить, что у вас есть данные в диапазоне "A1: H100" и заголовок в "A1: H1", который является первой строкой, тогда ваш диапазон данных должен быть "A2: H100", который необходимо упомянуть в свойстве "sourcesource" Значение свойства "and" columnheads "должно быть истинным

С уважением, Асиф Хамид

2 голосов
/ 14 декабря 2016

Мне нравится использовать следующий подход для заголовков в ComboBox, где CboBx не загружается с листа (например, данные из sql). Причина, по которой я указываю не на листе, заключается в том, что я думаю, что единственный способ заставить RowSource работать, если вы загружаетесь с листа.

Это работает для меня:

  1. Создайте свой ComboBox и создайте ListBox с идентичным макетом, но только с одной строкой.
  2. Поместите ListBox прямо поверх ComboBox.
  3. В вашем VBA загрузите ListBox row1 с желаемыми заголовками.
  4. В вашем VBA для действия yourListBoxName_Click введите следующий код:

    yourComboBoxName.Activate`
    yourComboBoxName.DropDown`
    
  5. Когда вы щелкаете по списку, выпадающий список выпадает из списка и функционирует нормально, а заголовки (в списке) остаются над списком.

0 голосов
/ 24 декабря 2018

Вот мое решение.

Я заметил, что когда я указываю источник строк списка через окно свойств в VBE, заголовки не возникают. Только когда мы пытаемся определить источник строк через код VBA, заголовки теряются.

Итак, сначала я определил источник строк списков как именованный диапазон в VBE для окна свойств, затем я могу сбросить источник строк в коде VBA. Заголовки по-прежнему отображаются каждый раз.

Я использую это в сочетании с расширенным макросом фильтра из объекта listobject, который затем создает другой (отфильтрованный) объект listobject, на котором основан источник строк.

Это сработало для меня

0 голосов
/ 02 ноября 2018

Я долго искал решение, чтобы добавить заголовок, не используя отдельный лист, и скопировать все в пользовательскую форму.

Мое решение состоит в том, чтобы использовать первую строку в качестве заголовка, пропустить ее через условие if и добавить под ней дополнительные элементы.

Вот так:

If lborowcount = 0 Then
 With lboorder
 .ColumnCount = 5
 .AddItem
 .Column(0, lborowcount) = "Item"
 .Column(1, lborowcount) = "Description"
 .Column(2, lborowcount) = "Ordered"
 .Column(3, lborowcount) = "Rate"
 .Column(4, lborowcount) = "Amount"
 End With
 lborowcount = lborowcount + 1
End If
        
        
With lboorder
 .ColumnCount = 5
 .AddItem
 .Column(0, lborowcount) = itemselected
 .Column(1, lborowcount) = descriptionselected
 .Column(2, lborowcount) = orderedselected
 .Column(3, lborowcount) = rateselected
 .Column(4, lborowcount) = amountselected
 
 
 End With

lborowcount = lborowcount + 1

в этом примере lboorder - это список, lborowcount считает, в какой строке добавить следующий элемент списка. Это список из 5 столбцов. Не идеально, но это работает, и когда вам нужно прокрутить горизонтально, «заголовок» остается над строкой.

0 голосов
/ 08 мая 2018

Вы можете попробовать. Я новичок в форуме, но хотел предложить что-то, что сработало для меня, так как в прошлом я получал большую помощь от этого сайта. Это, по сути, вариант вышеупомянутого, но я нашел его проще.

Просто вставьте это в раздел Userform_Initialize вашего кода пользовательской формы. Обратите внимание, что у вас уже должен быть список в пользовательской форме или он был создан динамически над этим кодом. Также обратите внимание, что Массив - это список заголовков (ниже как «Заголовок1», «Заголовок2» и т. Д. Замените их собственными заголовками. Этот код затем установит полосу заголовка вверху на основе ширины столбцов списка). Извините, он не прокручивается - это фиксированные метки.

Более старшие программисты - пожалуйста, не стесняйтесь комментировать или улучшать это.

    Dim Mywidths As String
    Dim Arrwidths, Arrheaders As Variant
    Dim ColCounter, Labelleft As Long
    Dim theLabel As Object                

    [Other code here that you would already have in the Userform_Initialize section]

    Set theLabel = Me.Controls.Add("Forms.Label.1", "Test" & ColCounter, True)
            With theLabel
                    .Left = ListBox1.Left
                    .Top = ListBox1.Top - 10
                    .Width = ListBox1.Width - 1
                    .Height = 10
                    .BackColor = RGB(200, 200, 200)
            End With
            Arrheaders = Array("Header1", "Header2", "Header3", "Header4")

            Mywidths = Me.ListBox1.ColumnWidths
            Mywidths = Replace(Mywidths, " pt", "")
            Arrwidths = Split(Mywidths, ";")
            Labelleft = ListBox1.Left + 18
            For ColCounter = LBound(Arrwidths) To UBound(Arrwidths)
                        If Arrwidths(ColCounter) > 0 Then
                                Header = Header + 1
                                Set theLabel = Me.Controls.Add("Forms.Label.1", "Test" & ColCounter, True)

                                With theLabel
                                    .Caption = Arrheaders(Header - 1)
                                    .Left = Labelleft
                                    .Width = Arrwidths(ColCounter)
                                    .Height = 10
                                    .Top = ListBox1.Top - 10
                                    .BackColor = RGB(200, 200, 200)
                                    .Font.Bold = True
                                End With
                                 Labelleft = Labelleft + Arrwidths(ColCounter)

                        End If
             Next
0 голосов
/ 16 июня 2016

Почему бы просто не добавить метки в верхнюю часть списка, и если необходимы изменения, единственное, что вам нужно программно изменить, - это метки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...