Страницы: 1
RSS
фильтрация с использованием дерева
 
Уважаемые Форумчане! Суть вопроса такая. Имеется план счетов - таблица со счетами с которой строится дерево. Имеется журнал проводок (записей) по счетам. Нужно чтобы по выбранным на дереве счетам фильтровались строки в журнале. Счета могут быть в двух столбцах по Д (дебету) и К (кредиту). Или хотя бы  по одному из них. Но выбрать надо несколько (выбранное число может изменятся в зависимости от необходимости). Счет я взял в цифровом буквенном виде

вот код который должен бы это делать
Код
Private Sub TreeView1_NodeCheck(ByVal Node As MSComctlLib.Node)
Static s As String
Static k As Integer
'On Error Resume Next
Dim el As Node, ile%: ile = 0
For Each el In TreeView1.Nodes
 If el.Checked = True Then ile = ile + 1
Next

Dim strNod As String

strNod = Node.Text
'выделяю номер счета
strNod = Left(strNod, InStr(1, Node.Text, " - ", 1))
s = s + strNod
k = k + 1
'strNod = Right(Node.Text, 1, Len(Node.Text) - 1)
Dim nds() As String
 ReDim Preserve nds(k)
 If k = 1 Then

Worksheets("выгрузка 1С").Activate
ActiveSheet.Range("a1:E1").AutoFilter Field:=4

' s = Left(s, Len(s) - 1)
'в выгрузке свой формат '01 - с кавычкой
s = "'" & s
nds = Split(s)

End If
ActiveSheet.Range("a1:h1").AutoFilter Field:=4, Criteria1:=Array(nds), Operator:=xlFilterValues

'ActiveSheet.Range("a1:h1").AutoFilter Field:=4, Criteria1:=.Keys
End Sub

Не могу разобраться с функцией Array - как я понял массив который она заполняет должен быть объявлен как Variant. А чтобы из строки получить массив - то массив - должен быть строковым. Может ли  функция Array применяться к массиву переменного размера.  
Изменено: fvi1967 - 18.09.2018 21:34:47
 
1. Оформите, пожалуйста код соответсвующим образом (при создании сообщения есть кнопочка.
2. Почему у Вас в файле примере один код (частично работающий, но с нерусскими комментариями), а тексте другой (вообще не работоспособный). Запихните его в файл-пример, чтобы люди не разбирались с 2-мя разными программами.
3. Array вообще ни при чём. Там до этого половина строчек не работает и nds всегда пустое, так что нужно сначала переписать всю программу и удостовериться, что к этой предпоследней строчке в nds что-то есть.
4. Пока пытался разобраться с программой постарался оставить комментарии по поводу того, почему она не может работать. В конце мои предложения по поводу переделки.
Код
Private Sub TreeView1_NodeCheck(ByVal Node As MSComctlLib.Node)
Static s As String 'Заявлена как статик, поэтому сохраняет значение при перезапуске процедуры. Процесс обнуления и изменения не предусмортен.
Static k As Integer 'По аналогии с предыдущим пунктом. Число k всегда растёт, массив для яильтров увеличивается, дубли не чистятся.

    Dim el As Node, ile%: ile = 0 'Совершенно не знакомая мне конструкция <ile%:>. Ну надо - значит надо.
    
    'в этом цикле считаем количество отмеченных полей и больше эту переменную нигде не используем.
    For Each el In TreeView1.Nodes
        If el.Checked = True Then ile = ile + 1
    Next
    
    Dim strNod As String 'На сколько я знаю, это плохая идея объявлять переменные посреди программы
    
    strNod = Node.Text 'присваиваем переменной текст пункта, на который нажали (неважно отсетили мы его или убрали выделение).
    strNod = Left(strNod, InStr(1, Node.Text, " - ", 1)) 'Отделяем цифровой код счёта
    s = s + strNod 'Добавляем цифровой код счёта к строке S
    k = k + 1 'Увеличиваем k на 1
    
    Dim nds() As String 'см пункт про объявление strNod посреди програмы
    ReDim Preserve nds(k) 'Можно и без Preserve массив всё-равно пустой
    
    If k = 1 Then 'Из-за того, что k статичное оно бывает равно 1 только при первом клике, при повторных запусках код вообще не исполняется.
        Worksheets("выгрузка 1С").Activate
        ActiveSheet.Range("a1:E1").AutoFilter Field:=4
        s = "'" & s 'S и так строка. Не совсем понятно, зачем к ней апостроф прибавлять
        nds = Split(s) 'Непривычно, что не указан разделитель (да, он по умолчанию, оказывается, пробел). Я бы всё-таки брал не s, а TRIM(s), чтобы избавиться от двойных пробелов.
    End If

    ActiveSheet.Range("a1:h1").AutoFilter Field:=4, Criteria1:=Array(nds), Operator:=xlFilterValues 'строчка если и может работать (непонятна конструкция Array(nds)), то всё-равно не работает из-за того, что массив nds всегда пуст.
    
'Что делать:
'1. Сделать k не Static, а просто dim.
'2. От s вообще избавиться.
'3. Перенести объявление всех переменных в начало.
'4. Массив nds формировать внутри цикла for Each el In TreeView1.Nodes
'   Для каждого el in TreeView1.Nodes
    '   Если el.Checked тогда..
        '   k=k+1
        '   strNod = el.Text
        '   далее- обработка StrNod (отделение цифрового кода + я бы пробелы убрал совсем)
        '   ReDim Preserve nds(k)
        '   nds(k) = обработанный strNod
     '  Конец если
'   Следующий el
'5. Всё. У нас сформирован массив кодов nds и можно пытаться запихать его в фильтр. Если не получится - обращайтесь на форум.
End Sub
Изменено: Wiss - 18.09.2018 14:34:37
Я не волшебник, я только учусь.
 
Код
 CommandButton1_Click()
Dim k As Integer
Dim el As Node
Dim strNod As String
Dim nds() As String
For Each el In TreeView1.Nodes
 If el.Checked = True Then
k = k + 1
 strNod = el.Text
 strNod = Left(strNod, InStr(1, el.Text, " - ", 1))
  ReDim Preserve nds(k)
 nds(k) = "'" & strNod
 End If
Next

Worksheets("выгрузка 1С").Activate

ActiveSheet.Range("a1:E1").AutoFilter
ActiveSheet.Range("a1:E1").AutoFilter Field:=4, Criteria1:=Array(nds), Operator:=xlFilterValues

End Sub
Согласен, всю критику принимаю, все поправил как смог понять. Добавка " ' "  из того чтобы решить проблему с форматами. Всякие счета типа 20.01 или 10.05 лист Excel быстренько преобразует  в даты типа - 20 января и тп
Я  с событием запускающим процедуру явно перемудрил ... это надо же было додуматься взять для фильтрации событие TreeView1_NodeCheck... . Конечно надо было сделать кнопку,  выбрать все что нужно ,  и  уже тогда сформировать фильтр. Вообщем  Вам спасибо!
Изменено: fvi1967 - 18.09.2018 21:28:44
 
Цитата
fvi1967 написал:
Согласен, всю критику принимаю
Цитата
Wiss написал:
1. Оформите, пожалуйста код соответсвующим образом
прикольно :)
 
fvi1967, Вы видели, как код оформлен у других? Вам об этом и говорят: оформляйте аналогично. Для этого есть специальная кнопка (см. скрин). Исправьте свои сообщения.
 
Catboyun, ну бывают и более рискованные трюки
По вопросам из тем форума, личку не читаю.
Страницы: 1
Наверх