Microsoft Excel:

  Таблицы и VBA. Справочник.
  Вопросы и Ответы. Советы. Примеры.
Меню FAQ | Макросы | MSForms


Rambler's Top100


Counter CO.KZ


    [1] [2] [2/1] [2 t] [3] [4]

  1. Как связать ListBox, ComboBox с диапазоном ячеек, в т.ч. и неактивного рабочего листа ? 16.06.2007
  2. Как присвоить переменной значение всех элементов списка ListBox, ComboBox ? 30.01.2005
  3. Как заполнить ячейки значениями всех элементов списка ListBox, ComboBox ? 15.09.2010
  4. Как быстро заполнить все элементы списка ListBox, ComboBox ? 30.01.2005
  5. Как вывести данные, расположенные в строке в виде столбца : ListBox, ComboBox ? 25.02.2006
  6. Как программно заполнить несколько столбцов в ComboBox, ListBox ? 07.07.2007
  7. Как сделать так, чтобы ListBox, ComboBox автоматически определял количество столбцов в источнике и отображал все столбцы ? 17.11.2010
  8. Как получить значение выбранного элемента списка в ComboBox, ListBox ? 03.09.2009
  9. Как получить все значения нужной строки в ListBox, ComboBox (без цикла) ? 24.09.2010
  10. Как получить все значения нужного столбца в ListBox, ComboBox (без цикла) ? 24.09.2010
  11. Как добавить данные в начало, середину или конец ComboBox, ListBox ? 24.08.2009
  12. Как динамически добавлять введённые данные в список ComboBox ? 28.03.2010
  13. Как оставить только выбранные элементы списка (список с многократным выделением) ? 01.08.2009
  14. Как удалить все выбранные элементы списка (список с многократным выделением) ? 06.06.2007
  15. Как удалить все повторяющиеся элементы списка ListBox, ComboBox ? 19.04.2008
  16. Как создать заголовки в ListBox, ComboBox ?
    Как создать заголовки для списка, где не используется свойство .RowSource ?
    25.02.2007
  17. Как установить ширину столбцов для списка ListBox пропорционально ширине столбцов диапазона=источника ? 03.04.2010
  18. Как менять ширину нужных столбцов ListBox ? 03.04.2010
  19. Как изменить цвет выделенного элемента списка ListBox ? 10.03.2008
  20. Как автоматически выделять строку в ListBox, находящуюся под курсором мышки ? 24.02.2010
  21. Как изменить цвет заливки отдельных элементов списка ListBox ? 17.10.2010
  22. Как перемещать выделенную строку ListBox вверх или вниз (используя кнопки) ? 04.09.2009
  23. Как перетаскивать/копировать данные из одного ListBox в другой (используя мышку) ? 19.04.2009
  24. Как перемещать/копировать данные из одного ListBox в другой (используя двойной клик мышки) ? 19.04.2009
  25. Как перемещать данные из одного ListBox в другой (используя кнопку) ? 19.04.2009
  26. Как отобразить дату в ComboBox где используется свойство .RowSource ? 19.10.2006
  27. Как программно отобразить выдающий список в ComboBox, а также определить его состояние ? 19.05.2014
  28. Как заполнить ListBox, ComboBox названиями месяцев или дней недели [без цикла] ? 09.02.2011
  29. Как прокручивать список в ComboBox используя колёсико мышки ? 27.07.2008
  30. Как сделать, чтобы в ComboBox каждый элемент списка был окрашен в свой цвет ? 10.10.2010
  31. Как используя мышку перетаскивать/копировать выделенный текст в TextBox, ComboBox ? 01.05.2009
  32. Как отобразить содержимое текстового файла в TextBox, ListBox (без построчного чтения) ? 27.05.2005
  33. Как заполнить ComboBox числами и сохранить возможность выводить наиболее подходящий элемент из списка ? NEW 26.08.2016
  34. Как очистить ComboBox, т.е. удалить все элементы списка, причём без цикла и вызова события ComboBox_Change() ? 08.06.2014
    [1] [2] [2/1] [2 t] [3] [4]


  • Ответ :

    Для того, чтобы связать список или поле со списком с диапазоном ячеек, достаточно найти свойство RowSource и ввести адрес нужного диапазона, например :
  • Ячейки активного листа : A2:A100
  • Ячейки конкретного листа "Сальдо" (активной рабочей книги) : Сальдо!A2:A100
  • Ячейки конкретного листа "Долг" рабочей книги "Клиенты.xls" (книга должна быть открыта) : [Клиенты.xls]Долг!A2:A100

    Примечание :
  • Допускается использование имени вместо адреса ячеек [FAQ]
  • Если диапазон состоит из нескольких столбцов, то необходимо использовать свойство ColumnCount [FAQ] иначе, будут отображаться данные только одного столбца.
  • Попытка заполнить элемент управления, с помощью свойства List или метода AddItem, уже после связывания с диапазоном, вызовет ошибку.
  • Ответ :
  • iMassiv = ListBox1.List
    iMassiv = ComboBox1.List

  • Ответ :
  • With ListBox1
         Range("A1").Resize(.ListCount, .ColumnCount).Value = .List
    End With
    With ComboBox1
         Worksheets(1).Range("C5").Resize(.ListCount, .ColumnCount).Value = .List
    End With
    Если значение свойства ColumnCount не устанавливается программно, то имеет смысл использовать следующий вариант
    With ListBox1
         Range("A1").Resize(.ListCount, UBound(.Column) + 1).Value = .List
    End With

  • Ответ :

    Вариант I. (с использ. переменной)
  • Private Sub UserForm_Initialize()
        iMassiv = Range("A1:C15").Value

        ListBox1.List = iMassiv
        ComboBox1.List = iMassiv
    End Sub
    Вариант I. (без использ. переменной)
    Private Sub UserForm_Initialize()
        ListBox1.List = Range("A1:C15").Value

        ComboBox1.List = Range("A1:C15").Value
    End Sub
    Вариант II. (с использ. переменной)
    Private Sub UserForm_Initialize()
        iAddress = Range("A1:C15").Address

        ListBox1.RowSource = iAddress
        ComboBox1.RowSource = iAddress
    End Sub
    Вариант II. (без использ. переменной)
    Private Sub UserForm_Initialize()
        ListBox1.RowSource = Range("A1:C15").Address

        ComboBox1.RowSource = Range("A1:C15").Address
    End Sub
    Если свойству RowSource вручную присвоен определённый адрес, то применение свойства List вызовет ошибку, которую впрочем можно избежать.

  • Ответ :

    Вариант I. (с использ. переменной)
  • Private Sub UserForm_Initialize()
        iMassiv = _
        Application.Transpose(Range("A1:J1"))

        ListBox1.List = iMassiv
        ComboBox1.List = iMassiv
    End Sub
    Вариант I. (без использ. переменной)
    Private Sub UserForm_Initialize()
        ListBox1.List = _
        Application.Transpose(Range("A1:J1"))

        ComboBox1.List = _
        Application.Transpose(Range("A1:J1"))
    End Sub
    Вариант II. (с использ. переменной)
    Private Sub UserForm_Initialize()
        iMassiv = Range("A1:J1").Value

        ListBox1.Column = iMassiv
        ComboBox1.Column = iMassiv
    End Sub
    Вариант II. (без использ. переменной)
    Private Sub UserForm_Initialize()
        ListBox1.Column = Range("A1:J1").Value

        ComboBox1.Column = Range("A1:J1").Value
    End Sub
    Вариант III.
    Private Sub UserForm_Initialize()
        For Each iCell In Range("A1:J1")
            ComboBox1.AddItem CStr(iCell.Value)
        Next
    End Sub
    Совет : Если диапазон содержит несколько строк, то необходимо использовать свойство ColumnCount, значение которого можно также установить вручную.
    Private Sub UserForm_Initialize()
        With Range("A1:J3")
             ListBox1.List = Application.Transpose(.Value)
             ListBox1.ColumnCount = .Rows.Count

             ComboBox1.List = Application.Transpose(.Value)
             ComboBox1.ColumnCount = .Rows.Count
        End With
    End Sub
    Private Sub UserForm_Initialize()
        With Range("A1:J3")
             ListBox1.Column = .Value
             ListBox1.ColumnCount = .Rows.Count

             ComboBox1.Column = .Value
             ComboBox1.ColumnCount = .Rows.Count
        End With
    End Sub

  • Ответ : Вопрос выбран посетителями

    Вариант I.

    Вы можете связать нужный элемент управления с диапазоном ячеек, который будет служить источником данных, с помощью свойства RowSource, установив при этом нужное количество столбцов, используя свойство ColumnCount. Эти действия можно осуществить как вручную [FAQ272], так и программно [FAQ34]

    Дополнение : Если необходимо, чтобы в ComboBox, ListBox отображались данные несмежных столбцов, воспользуйтесь следующим советом.

    Вариант II.
  • Private Sub UserForm_Initialize()
        Dim iMassiv(1 To 15, 1 To 3)
        For iRow& = 1 To 15
            iMassiv(iRow&, 1) = Cells(iRow&, 1)
            iMassiv(iRow&, 2) = Cells(iRow&, 3)
            iMassiv(iRow&, 3) = Cells(iRow&, 6)
        Next
        ListBox1.ColumnCount = 3
        ListBox1.List = iMassiv
    End Sub
    Private Sub UserForm_Initialize()
        Dim iMassiv$(1 To 15, 1 To 3)
        For iRow& = 1 To 15
            iMassiv$(iRow&, 1) = CStr(Cells(iRow&, "A"))
            iMassiv$(iRow&, 2) = CStr(Cells(iRow&, "C"))
            iMassiv$(iRow&, 3) = CStr(Cells(iRow&, "F"))
        Next
        ListBox1.ColumnCount = 3
        ListBox1.List = iMassiv$
    End Sub
    Вариант III.
    Private Sub UserForm_Initialize()
        With ListBox1
             Dim iCell As Range
             For Each iCell In Range("A1:A15")
                 .AddItem: iCount& = .ListCount - 1
                 .List(iCount&, 0) = CStr(iCell(1, 1))
                 .List(iCount&, 1) = CStr(iCell(1, 3))
                 .List(iCount&, 2) = CStr(iCell(1, 6))
             Next
             .ColumnCount = 3
        End With
    End Sub
    Private Sub UserForm_Initialize()
        For iRow& = 1 To 15
            ListBox1.AddItem Cells(iRow&, "A").Text
            ListBox1.List(iRow& - 1, 1) = Cells(iRow&, "C").Text
            ListBox1.List(iRow& - 1, 2) = Cells(iRow&, "F").Text
        Next
        ListBox1.ColumnCount = 3
    End Sub

  • Ответ :

    Если в процессе работы с ListBox, ComboBox Вам постоянно приходится определять количество столбцов в источнике данных и использовать полученные данные для установки, с помощью свойства ColumnCount, нужного количества столбцов в элементе управления, то всего этого можно избежать, если предварительно установить значение свойства ColumnCount = -1 (причём, осуществить это можно не только программно, но и вручную)
  • Ответ :

    Получить значение выделенного/выбранного элемента списка с однократным выделением, можно так :
  • Private Sub ListBox1_Click()
        MsgBox ListBox1.Value
    End Sub
    Private Sub ListBox1_Click()
        MsgBox ListBox1.List(ListBox1.ListIndex)
    End Sub
    Private Sub ListBox1_Click()
        MsgBox ListBox1.Column(0, ListBox1.ListIndex)
    End Sub
    Получить же значение выделенного/выбранного элемента списка с однократным выделением и несколькими столбцами, можно также, только необходимо указать индекс(номер) нужного столбца (обратите внимание на то, что отсчёт столбцов у свойства BoundColumn ведётся с 1, а нумерация столбцов в свойствах List, Column начинается с 0) :
    'Используйте свойство BoundColumn для того, чтобы
    'указать данные какого столбца необходимо получить

    Private Sub ListBox1_Click()
        MsgBox ListBox1.Value
    End Sub
    Private Sub ListBox1_Click()
        MsgBox ListBox1.List(ListBox1.ListIndex) 'Column1
        MsgBox ListBox1.List(ListBox1.ListIndex, 0) 'Column1
        MsgBox ListBox1.List(ListBox1.ListIndex, 1) 'Column2
    End Sub
    Private Sub ListBox1_Click()
        MsgBox ListBox1.Column(0, ListBox1.ListIndex) 'Column1
        MsgBox ListBox1.Column(1, ListBox1.ListIndex) 'Column2
    End Sub
    Комментарий : Всё вышеопубликованное справедливо и для ActiveX элемента управления ComboBox (поле со списком)

    Получить значения всех выделенных элементов списка с многократным выделением и несколькими столбцами, можно так :
    Private Sub ListBox1_Change()
        For iCount& = 0 To ListBox1.ListCount - 1
            If ListBox1.Selected(iCount&) = True Then
               MsgBox "Выбрано : " & ListBox1.List(iCount&) 'Column1
               MsgBox "Выбрано : " & ListBox1.List(iCount&, 0) 'Column1
               MsgBox "Выбрано : " & ListBox1.List(iCount&, 1) 'Column2
            End If
        Next
    End Sub
    Private Sub ListBox1_Change()
        With ListBox1
             For iCount& = 0 To .ListCount - 1
                 If .Selected(iCount&) = True Then
                    MsgBox "Выбрано : " & .Column(0, iCount&) 'Column1
                    MsgBox "Выбрано : " & .Column(1, iCount&) 'Column2
                 End If
             Next
        End With
    End Sub

  • Ответ :

    Получить значения всех столбцов нужной строки в ListBox, ComboBox с несколькими столбцами, причём без цикла, можно так :
  • iRow = 1 'первая строка
    iMassiv1 = Application.Index(ListBox1.List, iRow)
    iMassiv2 = Application.Index(ListBox1.Column, , iRow)
    iRow = 3 'третья строка
    iMassiv1 = Application.Index(ComboBox1.List, iRow)
    iMassiv2 = Application.Index(ComboBox1.Column, , iRow)
    Комментарий :
  • Подобный подход применим только к тем элементам управления, которые заполнялись с помощью свойств List / Column или RowSource
  • Первый массив удобно использовать, если Вы хотите полученные данные расположить в строке, а второй массив более приемлем при работе со столбцом.
  • Ответ :

    Получить значения всех строк нужного столбца в ListBox, ComboBox с несколькими столбцами, причём без цикла, можно так :
  • iColumn = 1 'первый столбец
    iMassiv1 = Application.Index(ListBox1.List, , iColumn)
    iMassiv2 = Application.Index(ListBox1.Column, iColumn)
    iColumn = 2 'второй столбец
    iMassiv1 = Application.Index(ComboBox1.List, , iColumn)
    iMassiv2 = Application.Index(ComboBox1.Column, iColumn)
    Комментарий :
  • Подобный подход применим только к тем элементам управления, которые заполнялись с помощью свойств List / Column или RowSource
  • Первый массив удобно использовать, если Вы хотите полученные данные расположить в столбце, а второй массив более приемлем при работе со строкой.
  • Ответ :

    Для того, чтобы добавить данные в начало списка достаточно :
  • ListBox1.AddItem "Первая строка", 0

    ComboBox1.AddItem "Первая строка", 0
    Для того, чтобы добавить данные (используя метод AddItem) в середину списка, нужно указать номер(индекс) элемента списка, после которого должна появиться новая строка, т.е.
    ListBox1.AddItem "Пятая строка", 4

    ComboBox1.AddItem "Пятая строка", 4
    Для того, чтобы добавить данные в конец списка, можно использовать следующий вариант :
    ListBox1.AddItem "Последняя строка"

    ComboBox1.AddItem "Последняя строка"
    Комментарий : Не забывайте, что :
  • Подобный подход не применим к элементам управления (ComboBox/ListBox), которые связаны с ячейками рабочего листа, т.е. заполнялись с помощью свойства RowSource / ListFillRange
  • Нумерация элементов списка всегда начинается с 0
  • Номер(индекс) новой строки не должен быть больше количества строк списка (свойство ListCount), т.е. Вы не можете добавить, к примеру, пятую строку, если список насчитывает всего три элемента
  • Ответ : Скачать пример

    Для того, чтобы введённые/скопированные данные, после нажатия клавиши ENTER становились частью списка, достаточно использовать нижеприведённый код
  • Private Sub ComboBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
        If KeyCode = vbKeyReturn Then
           With Me.ComboBox1
                .AddItem .Value
           End With
        End If
    End Sub

    Private Sub UserForm_Initialize()
        Me.ComboBox1.MatchRequired = True
    End Sub
    Private Sub ComboBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
        If KeyCode = vbKeyReturn Then ComboBox1.AddItem ComboBox1.Value
    End Sub
    Примечание : Обратите внимание на то, что здесь отсутствует проверка наличия добавляемого текста в списке, а стало быть нет никакой гарантии, что в списке не появятся повторы. В общем, если наличие повторящихся значений (дубликатов) нежелательно, то далее приведены три варианта, позволяющие не допустить их ввода.
    Private Sub ComboBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
        If KeyCode = vbKeyReturn Then
           With Me.ComboBox1
                If Not .MatchFound Then .AddItem .Value
           End With
        End If
    End Sub
    Private Sub ComboBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
        If KeyCode = vbKeyReturn Then
           With Me.ComboBox1
                iText$ = .Value
                If IsError(Application.Match(iText$, .List, 0)) = True Then
                   .AddItem iText$
                End If
           End With
        End If
    End Sub
    Private Sub ComboBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
        If KeyCode = vbKeyReturn Then
           If IsError(Application.Match(ComboBox1.Value, _
           ComboBox1.List, 0)) = True Then ComboBox1.AddItem ComboBox1.Value
        End If
    End Sub
    Комментарий : Подобный подход применим только к тем элементам управления ComboBox, которые заполнялись с помощью свойства List или Column.
    Если же при первоначальном заполнении поля со списком был использован метод AddItem, то проверить наличие текста в списке можно, например, так ...
    Option Compare Text

    Private Sub ComboBox1_KeyDown(ByVal KeyCode As msforms.ReturnInteger, ByVal Shift As Integer)
        If KeyCode <> vbKeyReturn Then Exit Sub

        With Me.ComboBox1
             iText$ = .Value
             For iCount& = 0 To .ListCount - 1
                 If .List(iCount&) = iText$ Then Exit Sub
             Next
             .AddItem iText$
        End With
    End Sub
    или так (по-умолчанию поиск осуществляется в первом столбце) :
    Private Sub ComboBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
        If KeyCode = vbKeyReturn Then
           With Me.ComboBox1
                If Not ItemIsExist(.List, .Value) Then .AddItem .Value
           End With
        End If
    End Sub

    Private Function ItemIsExist(iArray, iText$, Optional iColumn& = 0) As Boolean
        For iCount& = 0 To UBound(iArray)
            If iArray(iCount&, iColumn&) = iText$ Then
               ItemIsExist = True
               Exit Function
            End If
        Next
        ItemIsExist = False
    End Function

  • Ответ : Скачать пример

    Для того, чтобы в списке с многократным выделением оставить только выделенные элементы списка, можно воспользоваться одним из двух нижеприведённых вариантов, где за скрытие/отображение отвечает "флажок"

    Вариант I.
  • Private iMassiv As Variant
    
    Private Sub CheckBox1_Click()
        With ListBox1
             If CheckBox1.Value = True Then
                For iCount& = .ListCount - 1 To 0 Step -1
                    If Not .Selected(iCount&) Then .RemoveItem iCount&
                Next
             Else
                .List = iMassiv
             End If
        End With
    End Sub
    
    Private Sub UserForm_Initialize()
        iMassiv = [A2:A17]: ListBox1.List = iMassiv
    End Sub
    Вариант II. Создайте второй список (ListBox2), установите значения его свойств Top, Left, Height, Width равными соответствующим свойствам первого (ListBox1) списка, затем скройте второй список, т.е. просто установите значение свойства Visible = False. После чего используйте следующий код :
    Private Sub CheckBox1_Click()
        With ListBox1
             If CheckBox1.Value = True Then
                ListBox2.Clear
                For iCount& = 0 To .ListCount - 1
                    If .Selected(iCount&) = True Then _
                       ListBox2.AddItem .List(iCount&)
                Next
             End If
             ListBox2.Visible = CheckBox1.Value
        End With
    End Sub
    
    Private Sub UserForm_Initialize()
        ListBox1.List = [A2:A17].Value
    End Sub
    Примечание : При выборе варианта учитывайте особенности каждого, например, для списков, содержащих несколько столбцов проще использовать первый способ, т.к. там достаточно всего лишь изменить A2:A17 на A2:C17, однако, второй способ можно применять к спискам, которые связаны с ячейками рабочего листа [FAQ272], и т.д.
  • Ответ : Скачать пример
  • For iCount& = ListBox1.ListCount - 1 To 0 Step -1
        If ListBox1.Selected(iCount&) = True Then _
           ListBox1.RemoveItem iCount&
    Next
    With Me.ListBox1
         For iCount& = .ListCount - 1 To 0 Step -1
             If .Selected(iCount&) = True Then .RemoveItem iCount&
         Next
    End With

  • Ответ : Скачать пример

    Для того, чтобы удалить все повторяющиеся элементы списка и в результате получить список, содержащий только уникальные значения, достаточно воспользоваться процедурой UniqueItems
  • Private Sub UniqueItems()
        With Me.ComboBox1 'ListBox1
             iMassiv = .List
             For iCount& = .ListCount - 1 To 0 Step -1
                 If iCount& <> Application.Match(iMassiv( _
                 iCount&, 0), iMassiv, 0) - 1 Then .RemoveItem iCount&
             Next
        End With
    End Sub
    Комментарий : Подобный подход применим только к тем элементам управления (ComboBox/ListBox), которые заполнялись с помощью свойства List или Column
  • Ответ : Скачать пример
    Если элемент управления связан с ячейками рабочего листа, посредством использования свойства RowSource/ListFillRange, то создать заголовки можно применив свойство ColumnHeads [FAQ]
    В противном случае, создать собственные заголовки, можно использовав элемент управления Label и свойство Caption. Небольшой пример создания подобных заголовков можно скачать здесь.
  • Ответ : Скачать пример
    Если в качестве источника данных для ListBox, ComboBox используется диапазон ячеек, то иногда возникает необходимость установить ширину столбцов ListBox пропорциально ширине столбцам диапазона. В принципе, вычислить пропорции можно и вручную, а затем просто установить нужную ширину, использовав свойство ColumnWidths [FAQ], но т.к. ширина столбцов диапазона может меняться, то имеет смысл использовать следующий код, естественно, указав свой диапазон и выбрав нужный "тип связывания" списка с диапазоном.
  • Private Sub UserForm_Initialize()
        With ThisWorkbook.Worksheets(1).Range("A1:E100")         
             iPercent# = (Me.ListBox1.Width * 0.95) / .Columns.Width
             Dim iColumn As Range
             For Each iColumn In .Columns
                 iWidth$ = iWidth$ & ";" & Fix(iColumn.Width * iPercent#)
             Next
             Me.ListBox1.List = .Resize(.Rows.Count - 1).Offset(1).Value
             Me.ListBox1.ColumnCount = .Columns.Count
             Me.ListBox1.ColumnWidths = Mid(iWidth$, 2)
        End With
    End Sub
    Private Sub UserForm_Initialize()
        With ThisWorkbook.Worksheets(1).Range("A1:E100")         
             iPercent# = .Columns.Width / (Me.ListBox1.Width * 0.95)
             Dim iColumn As Range
             For Each iColumn In .Columns
                 iWidth$ = iWidth$ & ";" & Fix(iColumn.Width / iPercent#)
             Next
             Me.ListBox1.RowSource =  _
             .Resize(.Rows.Count - 1).Offset(1).Address(External:=True)
             Me.ListBox1.ColumnHeads = True
             Me.ListBox1.ColumnCount = .Columns.Count
             Me.ListBox1.ColumnWidths = Mid(iWidth$, 2)
        End With
    End Sub
    Предполагается, что диапазон - источник содержит заголовок (шапку), в противном случае использовать свойства Resize, Offset, ColumnHeads не нужно.

    Комментарий :
  • Подобные действия не гарантируют, что Вы сможете прочитать полностью текст ячейки
  • Если количество столбцов в диапазоне меняться не будет, то установить значение свойства ColumnCount можно вручную [FAQ]
  • Значение свойства ColumnHeads также можно установить вручную
  • Ответ : Скачать пример
    Для того, чтобы изменить ширину столбца ListBox, ComboBox нужно использовать свойство свойство ColumnWidths. Небольшой пример можно скачать здесь.
  • Ответ : Скачать пример
    К сожалению, напрямую управлять цветом выделенного элемента списка, нельзя, однако, использовав дополнительно ещё и элемент управления Frame, добиться нужного эффекта всё таки можно. Небольшой пример "подсветки строки" выделенной с помощью мышки или клавиши вверх/вниз, можно скачать здесь.
  • Ответ : Скачать пример
    Для того, чтобы строка выделялась автоматически (т.е. без дополнительных действий, например, клика мышкой и т.п.) после наведения на неё курсора мышки, можно использовать событие ListBox1_MouseMove и следующий код, где 10 = это размер шрифта Tahoma * 1,22(1,25)
  • Private Sub ListBox1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
         With Me.ListBox1
              .Selected(.TopIndex + Y \ 10) = True
         End With
    End Sub

  • Ответ : Скачать пример
    Для того, чтобы перемещать выделенную строку вверх или вниз, достаточно создать две кнопки и воспользоваться процедурой ExchangeItems, указав нужное смещение (см. далее)
  • Private Sub CommandButton1_Click() 'Вверх
        ExchangeItems ListBox1, 1
    End Sub
    
    Private Sub CommandButton2_Click() 'Вниз
        ExchangeItems ListBox1, -1
    End Sub
    
    Private Sub ExchangeItems(ListBox As MSForms.ListBox, Step As Integer)
        Dim iSelIndex As Long
        Dim iColumn   As Long
        Dim iValue As Variant
        With ListBox
             iSelIndex = .ListIndex - Step
             For iColumn = 0 To .ColumnCount - 1
                 iValue = .List(iSelIndex, iColumn)
                 .List(iSelIndex, iColumn) = _
                 .List(iSelIndex + Step, iColumn)
                 .List(iSelIndex + Step, iColumn) = iValue
             Next
             .ListIndex = iSelIndex '.Selected(iSelIndex) = True
        End With
    End Sub
    Комментарий :
  • Подобный подход применим только к тем элементам управления, которые заполнялись с помощью метода AddItem или свойств List/Column
  • Не забывайте, что нельзя переместить вверх первую строку и, соответственно, последнюю строку нельзя переместить вниз.
  • Ответ : Скачать пример
    Для того, чтобы с помощью мышки можно было перетаскивать данные из одного ListBox в другой, достаточно воспользоваться следующим кодом. Если же вместо перемещения элементов Вам необходимо их копировать, то просто закомментируйте/удалите ненужную строку в событии ListBox1_BeforeDropOrPaste.
  • Private iDataObject As New DataObject 'MSForms.DataObject

    Private Sub ListBox1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
        If Button = vbKeyLButton Then iDataObject.StartDrag
    End Sub

    Private Sub ListBox2_BeforeDragOver(ByVal Cancel As MSForms.ReturnBoolean, ByVal Data As MSForms.DataObject, ByVal X As Single, ByVal Y As Single, ByVal DragState As Long, ByVal Effect As MSForms.ReturnEffect, ByVal Shift As Integer)
        Cancel = True
    End Sub

    Private Sub ListBox2_BeforeDropOrPaste(ByVal Cancel As MSForms.ReturnBoolean, ByVal Action As Long, ByVal Data As MSForms.DataObject, ByVal X As Single, ByVal Y As Single, ByVal Effect As MSForms.ReturnEffect, ByVal Shift As Integer)
        ListBox2.AddItem ListBox1.Value 'EffectCopy
        ListBox1.RemoveItem ListBox1.ListIndex 'EffectMove

        If ListBox1.ListCount = 0 Then ListBox1.Enabled = False
    End Sub
    Предполагается, что нам необходимо перетаскивать данные из ListBox1 в ListBox2, причём ListBox1 это список с однократным выделением, т.е. значение свойства MultiSelect = 0 'fmMultiSelectSingle
  • Ответ : Скачать пример
    Для того, чтобы с помощью двойной клика мышки, можно было переместить выбранный элемент списка из одного ListBox в другой, достаточно воспользоваться следующим кодом. Если же вместо перемещения элементов Вам необходимо их копировать, то просто закомментируйте/удалите ненужную строку в событии ListBox1_DblClick.
    Если возникнет необходимость в двухстороннем обмене данными, то Вы можете воспользоваться процедурой ListBox_Swap, которая опубликована в следующем совете.
  • Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
        If ListBox1.ListCount > 0 Then
           ListBox2.AddItem ListBox1.Value 'EffectCopy
           ListBox1.RemoveItem ListBox1.ListIndex 'EffectMove
        End If
    End Sub
    Предполагается, что нам необходимо перемещать данные из ListBox1 в ListBox2, причём ListBox1 это список с однократным выделением, т.е. значение свойства MultiSelect = 0 'fmMultiSelectSingle
  • Ответ : Скачать пример
    Для того, чтобы организовать двухсторонний обмен данными между двумя ListBox, т.е. перемещать, с помощью соответствующей кнопки, выбранный элемента списка из одного ListBox в другой, достаточно создать две кнопки (и, разумеется, два списка) и воспользоваться процедурой ListBox_Swap.
  • Private Sub CommandButton1_Click()
        ListBox_Swap ListBox1, ListBox2
    End Sub

    Private Sub CommandButton2_Click()
        ListBox_Swap ListBox2, ListBox1
    End Sub

    Private Sub ListBox_Swap(ListBoxCopy As MSForms.ListBox, ListBoxMove As MSForms.ListBox)
        With ListBoxCopy
             If .ListIndex > -1 Then _
             ListBoxMove.AddItem .Value: .RemoveItem .ListIndex
        End With
    End Sub
    Предполагается, что оба ListBox'а это списки с однократным выделением, т.е. значение их свойств MultiSelect = 0 'fmMultiSelectSingle
  • Ответ : Скачать пример
  • Private Sub ComboBox1_Change()
        iDate$ = Format(ComboBox1.Value, "dd/mm/yyyy")
        If IsDate(iDate$) = True Then _
           ComboBox1.Value = iDate$
    End Sub

  • Ответ :

    Для того, чтобы программно отобразить выпадающий список у элемента управления ComboBox, достаточно использовать метод DropDown
  • ComboBox1.DropDown
    Если же возникнет необходимость в определении "видимости" выпадающего списка, то учитывая тот факт, что у поля со списком нет соответствующего свойства, нам придётся прибегнуть к небольшому финту, а именно, использовать событие ComboBox1_DropButtonClick и переменную, об'явленную на уровне модуля :
    Private iDropDown As Boolean

    Private Sub ComboBox1_DropButtonClick()
        iDropDown = Not iDropDown
    End Sub
    Теперь, когда понадобится узнать состояние выпадающего списка,Вы сможете узнать это, использовав переменную iDropDown ( True - отображён/виден, False - нет )
  • Ответ :

    Для того, чтобы заполнить элемент управления Список - ListBox, или Поле со списком - ComboBox названиями дней недели или месяцев, причём, без цикла, достаточно использовать следующие варианты :

    Вариант I. (зависит от языка)
  • ListBox1.List = Application.GetCustomListContents(2)

    ComboBox1.List = Application.GetCustomListContents(1)
    ListBox1.List = Application.GetCustomListContents(4)

    ComboBox1.List = Application.GetCustomListContents(3)
    Примечание : Этот способ имеет смысл применять в тех, случаях, когда месяца и дни должны отображаться в зависимости от языка офиса, т.е. если офис руссифицирован то на русском, если же речь идёт о немецко-язычном офисе, то, соответственно, на немецком. Впрочем, есть вероятность, что ранние версии, например, XL97 будут возвращать имена всё равно в английском варианте (вне зависимости от того руссифицирован Ваш офис или нет)

    Вариант II. (не зависит от языка)
    ListBox1.List = Array("Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье")

    ComboBox1.List = Array("Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье")
    ListBox1.List = Array("Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь")

    ComboBox1.List = Array("Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь")

  • Ответ :

    Для того, чтобы с помощью мышки, можно было перетащить/скопировать выделенный текст из одного поля (TextBox, ComboBox) в другой, достаточно :
    - установить у нужного элемента управления значение свойства DragBehavior как fmDragBehaviorEnabled
    - выделить необходимый текст
    - кликнуть правой(левой) кнопой мышки *, и не отпуская её, переместить курсор мышки к нужному месту поля, а затем отпустить кнопку (* для копирования необходимо нажать ещё и клавишу CTRL)

    Комментарий : Для того, чтобы перемещение/копирование в ComboBox стало возможным, необходимо также установить значение свойства Style как fmStyleDropDownCombo. Кроме того, не стоит забывать, что перемещенные/скопированные, подобным способом, данные не становятся частью списка.
  • Ответ :

    Если необходимо заполнить ComboBox числами, но сохранить возможность выводить наиболее подходящий элемент из списка [FAQ] , то выберите любой из вышеопубликованных вариантов [FAQ34], [FAQ272] за исключением :
  • ComboBox1.List = Range("A1:A100").Value
    Впрочем, если очень хочется применить свойство .List, то можно использовать такой финт, только запомните, что в этом случае, мы заполним ComboBox1 текстом.
    ComboBox1.List = Application.Trim(Range("A1:A100"))
    Комментарий : Если же Вы проигнорируете это напоминание, и не будете учитывать сей факт, то получите неприятный сюрприз (см. второе сообщение)
    Private Sub UserForm_Initialize() 'Демонстрация
        Range("A1") = 7: Range("A2") = 10.25
    
        With ComboBox1
             .List = Range("A1:A2").Value
             MsgBox .List(0, 0) + .List(1, 0)
             
             .List = Application.Trim(Range("A1:A2"))
             MsgBox .List(0, 0) + .List(1, 0)
             
             MsgBox Val(.List(0, 0)) + Val(.List(1, 0))
             
             MsgBox Application.Sum(.List(0, 0), .List(1, 0))
        End With
    End Sub
    Если же числа в исходном диапазоне не являются результатом вычисления формул, то заполнить ComboBox1 текстом можно, если вместо свойства .Value использовать свойство .Formula , т.е.
    ComboBox1.List = Range("A1:A100").Formula

  • Ответ :

    Вариант I. Для того, чтобы очистить ComboBox, достаточно использовать метод Clear, т.е.
  • ComboBox1.Clear
    Однако, не стоит забывать, что этот метод не только удаляет все элементы списка, но и удаляет выбранный(или введённый) текст в поле этого элемента управления, что в свою очередь, приводит к вызову события ComboBox1_Change

    Вариант II. Если же Вам нужно удалить все элементы списка, но оставить данные текстового поля, то используйте свойство List и VB(A) функцию Array, т.е. :
    ComboBox1.List = Array()
    Если же Вам нужно полностью очистить поле со списком, но при этом, не вызывать событие ComboBox_Change, то используйте следующий вариант :
    ComboBox1.List = Array()
    ComboBox1.ListIndex = -1

    Воспроизведение любых опубликованных здесь материалов возможно только с письменного разрешения автора : Microsoft Excel 95, 97, 2000, XP

    © 2004-2016 Климов П.Ю. Все права защищены. WebDesign & Error's Klimoff