Добрый день. Имеется таблица реестр . На основании таблицы можно формировать отчет по Клиенту: выбираем период,клиента (выделена одна опция в Листбоксе) все работает. Вопрос :а как можно подкорректировать код ,что бы можно было выделять несколько опций и формировать отчет? При инициализации формы сейчас : [vba]
Код
Me.ListBox1.MultiSelect = fmMultiSelectMulti
[/vba] В прилагаемом файле на Листе "Карточка" есть вариант как должно быть . Заранее благодарен.
Добрый день. Имеется таблица реестр . На основании таблицы можно формировать отчет по Клиенту: выбираем период,клиента (выделена одна опция в Листбоксе) все работает. Вопрос :а как можно подкорректировать код ,что бы можно было выделять несколько опций и формировать отчет? При инициализации формы сейчас : [vba]
Код
Me.ListBox1.MultiSelect = fmMultiSelectMulti
[/vba] В прилагаемом файле на Листе "Карточка" есть вариант как должно быть . Заранее благодарен.parovoznik
В Call Report передаем массив выбранных значений и их количество. [vba]
Код
'Кнопка Сформировать Private Sub ButtonReport_Click() Dim a(), i As Long, k As Long '........................................ здесь все, что до строки Firma = Me.ListBox1.Value ' Firma = Me.ListBox1.Value
With ListBox1 ReDim a(1 To .ListCount)
For i = 0 To .ListCount - 1 If .Selected(i) = True Then k = k + 1: a0(k) = .List(i) End If Next i End With
Call Report(a0, k) Unload Me End Sub
[/vba] В процедуре циклом по этому массиву [vba]
Код
Sub Report(a0(), k As Long) Dim n As Long '....................... If Reestr.Cells(i, 4) <= DateFinish Then For n = 1 To k If Reestr.Cells(i, 6) = a0(n) Then .Cells(LR, 1) = Reestr.Cells(i, 1).Value '.......................
[/vba] Только правка по вопросу. По хорошему - всю обработку перенести в массивы (к листу обращаться при первичном чтении и для выгрузки).
В Call Report передаем массив выбранных значений и их количество. [vba]
Код
'Кнопка Сформировать Private Sub ButtonReport_Click() Dim a(), i As Long, k As Long '........................................ здесь все, что до строки Firma = Me.ListBox1.Value ' Firma = Me.ListBox1.Value
With ListBox1 ReDim a(1 To .ListCount)
For i = 0 To .ListCount - 1 If .Selected(i) = True Then k = k + 1: a0(k) = .List(i) End If Next i End With
Call Report(a0, k) Unload Me End Sub
[/vba] В процедуре циклом по этому массиву [vba]
Код
Sub Report(a0(), k As Long) Dim n As Long '....................... If Reestr.Cells(i, 4) <= DateFinish Then For n = 1 To k If Reestr.Cells(i, 6) = a0(n) Then .Cells(LR, 1) = Reestr.Cells(i, 1).Value '.......................
[/vba] Только правка по вопросу. По хорошему - всю обработку перенести в массивы (к листу обращаться при первичном чтении и для выгрузки).vikttur
Сообщение отредактировал vikttur - Пятница, 25.01.2019, 16:14
vikttur, спасибо за код . Выдает ошибку в этом блоке:"Функция не определена" [vba]
Код
With ListBox1 ReDim a(1 To .ListCount) For i = 0 To .ListCount - 1 If .Selected(i) = True Then k = k + 1: [b]a0(k) [/b]= .List(i) End If Next i End With
[/vba]
vikttur, спасибо за код . Выдает ошибку в этом блоке:"Функция не определена" [vba]
Код
With ListBox1 ReDim a(1 To .ListCount) For i = 0 To .ListCount - 1 If .Selected(i) = True Then k = k + 1: [b]a0(k) [/b]= .List(i) End If Next i End With
vikttur, все исправил ,но выдает ошибку : compile error Вот весь код : [vba]
Код
Sub Report(a0(), k As Long) Dim n As Long Dim i As Long, LastRow As Long, LR As Long
LR = 5 ' Указали, что первая свободная строка для нового отчёта будет =5 With Card 'Применительно ко второму листу LastRow = .Cells(Rows.Count, 1).End(xlUp).row 'Нашли последнюю строку на втором листе Range(.Cells(5, 1), .Cells(LastRow + 1, 4)).Clear 'Очистили диапазон отчета полностью .Cells(2, 2).ClearContents 'Очистили ЗНАЧЕНИЯ в шапке отчета .Cells(2, 2) = "Отчет с " & DateStart & " по " & DateFinish 'Заполнили заголовок отчета .Cells(3, 2) = "Карточка: " & Firma LastRow = Cells(Rows.Count, 1).End(xlUp).row 'Нашли последнюю строку на первом листе For i = 3 To LastRow 'Начали цикл (на первом листе) со строки № 3 по последнюю If Reestr.Cells(i, 4) >= DateStart Then If Reestr.Cells(i, 4) <= DateFinish Then For n = 1 To k If Reestr.Cells(i, 6) = a0(n) Then .Cells(LR, 1) = Reestr.Cells(i, 1).Value .Cells(LR, 2) = Reestr.Cells(i, 4).Value .Cells(LR, 3) = Reestr.Cells(i, 6).Value .Cells(LR, 4) = Reestr.Cells(i, 7).Value LR = LR + 1 'Увеличили на единичку номер первой свободной строки отчета End If End If End If Next n Next i 'Заполним подвал отчета .Cells(LR, 1) = "Итого:" .Cells(LR, 4) = Application.WorksheetFunction.Sum(Range(.Cells(5, 4), .Cells(LR - 1, 4))) 'Посчитали сумму отчета Range(.Cells(5, 1), .Cells(LR, 4)).Borders.LineStyle = xlContinuous 'Сделали обрамление ячеек End With If LR = 5 Then MsgBox "По данными критериям данных не найдено!", 64, "Сообщение" End Sub
[/vba]
vikttur, все исправил ,но выдает ошибку : compile error Вот весь код : [vba]
Код
Sub Report(a0(), k As Long) Dim n As Long Dim i As Long, LastRow As Long, LR As Long
LR = 5 ' Указали, что первая свободная строка для нового отчёта будет =5 With Card 'Применительно ко второму листу LastRow = .Cells(Rows.Count, 1).End(xlUp).row 'Нашли последнюю строку на втором листе Range(.Cells(5, 1), .Cells(LastRow + 1, 4)).Clear 'Очистили диапазон отчета полностью .Cells(2, 2).ClearContents 'Очистили ЗНАЧЕНИЯ в шапке отчета .Cells(2, 2) = "Отчет с " & DateStart & " по " & DateFinish 'Заполнили заголовок отчета .Cells(3, 2) = "Карточка: " & Firma LastRow = Cells(Rows.Count, 1).End(xlUp).row 'Нашли последнюю строку на первом листе For i = 3 To LastRow 'Начали цикл (на первом листе) со строки № 3 по последнюю If Reestr.Cells(i, 4) >= DateStart Then If Reestr.Cells(i, 4) <= DateFinish Then For n = 1 To k If Reestr.Cells(i, 6) = a0(n) Then .Cells(LR, 1) = Reestr.Cells(i, 1).Value .Cells(LR, 2) = Reestr.Cells(i, 4).Value .Cells(LR, 3) = Reestr.Cells(i, 6).Value .Cells(LR, 4) = Reestr.Cells(i, 7).Value LR = LR + 1 'Увеличили на единичку номер первой свободной строки отчета End If End If End If Next n Next i 'Заполним подвал отчета .Cells(LR, 1) = "Итого:" .Cells(LR, 4) = Application.WorksheetFunction.Sum(Range(.Cells(5, 4), .Cells(LR - 1, 4))) 'Посчитали сумму отчета Range(.Cells(5, 1), .Cells(LR, 4)).Borders.LineStyle = xlContinuous 'Сделали обрамление ячеек End With If LR = 5 Then MsgBox "По данными критериям данных не найдено!", 64, "Сообщение" End Sub
Только правка по вопросу. По хорошему - всю обработку перенести в массивы (к листу обращаться при первичном чтении и для выгрузки).
vikttur,если есть возможность прокомментировать использования кода и как это можно воплотить в моем коде. Я на протяжении многих лет пользовался этим кодом и вот пришлось доработать,а оказывается есть еще варианты. Дякую. Pelena , благодарю за помощь.
Только правка по вопросу. По хорошему - всю обработку перенести в массивы (к листу обращаться при первичном чтении и для выгрузки).
vikttur,если есть возможность прокомментировать использования кода и как это можно воплотить в моем коде. Я на протяжении многих лет пользовался этим кодом и вот пришлось доработать,а оказывается есть еще варианты. Дякую. Pelena , благодарю за помощь. parovoznik
прокомментировать... и как это можно воплотить в моем коде
Читайте о массивах. Коротко. Работа с объектами листа медленная. Данные с листа записываются в массив, в процессе обрабтки результат записывается во второй массив (или в этот же, в 2-3 других - зависит от задачи). После обработки данные одним действием выгружаются на лист. Этим достигается многократное увеличение скорости работы макроса.
Цитата
прокомментировать... и как это можно воплотить в моем коде
Читайте о массивах. Коротко. Работа с объектами листа медленная. Данные с листа записываются в массив, в процессе обрабтки результат записывается во второй массив (или в этот же, в 2-3 других - зависит от задачи). После обработки данные одним действием выгружаются на лист. Этим достигается многократное увеличение скорости работы макроса.vikttur