Страницы: 1
RSS
Связанные списки в VBA, Не могу найти причину ошибки
 
Здравствуйте, уважаемые знатоки VBA. Сделал связь между списками в форме VBA с помощью Worksheetfunction, но при нескольких кликах на разных значениях выдает ошибку 1004. Уже всю душу вымотал в поисках ошибки - там кода-то две строчки всего! Что я сделал не так и как это можно исправить? Есть ли другие способы связи списков, кроме как через Worksheetfunction? Заранее благодарен за обстоятельный ответ.
 
Добавил пропуск ошибки - вроде работает
Код
Private Sub LBproperty_Change()
On Error Resume Next
LBpriznak.RowSource = "H" & WorksheetFunction.Match(LBtovar.Value & LBproperty.Value, Range("G2:G27"), 0) _
    + 1 & ":H" & WorksheetFunction.Match(LBtovar.Value & LBproperty.Value, Range("G2:G27"), 0) + _
    WorksheetFunction.CountIf(Range("G2:G27"), LBtovar.Value & LBproperty.Value)
End Sub
Изменено: Ёк-Мок - 14.10.2014 13:32:36
Удивление есть начало познания © Surprise me!
И да пребудет с нами сила ВПР.
 
но по прежнему интересна причина ошибки
Изменено: Ёк-Мок - 14.10.2014 13:32:47
Удивление есть начало познания © Surprise me!
И да пребудет с нами сила ВПР.
 
конкретно в вашем случае ошибка возникает сразу в куче случаев, в основном связанных с тем, что в процессе "перекликивания" теряется значение LBproperty, и функция Match не может найти значение.
Если поставить во вторую процедуру msgbox-ы с выводом LBproperty, всё станет очень наглядно.

Замените в процедуре LBtovar_Click() закомментированные строки на вот эту:
Код
LBpriznak.RowSource = ""
'LBproperty.ListIndex = -1
'LBproperty.ListIndex = 0 
вообще же это какой-то немного извращенный способ, конечно  :)
F1 творит чудеса
 
Цитата
Максим Зеленский пишет: в процессе "перекликивания" теряется значение LBproperty
Это ясно (при дебаге видно значение LBproperty.Value=Null). Но почему значение теряется?
Изменено: Ёк-Мок - 14.10.2014 21:26:48
Удивление есть начало познания © Surprise me!
И да пребудет с нами сила ВПР.
 
Я думаю потому, что если в первой процедуре ошибка в Match, остальные строки в ней игнорируются
неверно.

Думал, что проблема в присвоении нового LBproperty.RowSource в процедуре LBtovar_Click, что вызывало событие LBproperty_Change() - но ListIndex там был -1
Думал, что вот так работает совсем без ошибок.
Код
Private Sub LBtovar_Click()
frow = WorksheetFunction.Match(LBtovar.Value, Range("D2:D14"), 0)
lrow = frow + WorksheetFunction.CountIf(Range("D2:D14"), LBtovar.Value)
Application.EnableEvents = False
LBproperty.RowSource = "E" & (frow + 1) & ":E" & lrow
Application.EnableEvents = True
LBproperty.Value = LBproperty.List(0)
End Sub
Private Sub LBproperty_Change()
one = WorksheetFunction.Match(LBtovar.Value & LBproperty.Value, Range("G2:G27"), 0)
two = one + WorksheetFunction.CountIf(Range("G2:G27"), LBtovar.Value & LBproperty.Value)
LBpriznak.RowSource = "H" & one + 1 & ":H" & two
End Sub
однако нет - при запуске формы и выборе Товар1 через раз значение LBproperty.Value не присваивается
Изменено: Максим Зеленский - 14.10.2014 15:07:47
F1 творит чудеса
 
Друзья, а что надо дописать, чтобы значение не терялось? Я тоже уже пробовал "перекликивать" и с помощью .ListIndex .и с помощью SetFocus - все равно ошибка выходит.
 
Ну так ИМХО
Код
On Error Resume Next

решает задачу, несмотря на причину ошибки (пост #3 см.файл)
Изменено: Ёк-Мок - 15.10.2014 00:45:24
Удивление есть начало познания © Surprise me!
И да пребудет с нами сила ВПР.
 
Имхо, использовать WorksheetFunction в макросе... только в крайних случаях...
вместо листбоксов сделал комбобоксы, т.к. , имхо, они более подходят для выпадающих списков.
Для листбоксов все тоже самое.

Code
Изменено: Михаил С. - 15.10.2014 01:24:35
 
Да, Михаил! С комбобоксами работает! Я тоже верил, что WorksheetFunction в макросах - это признак неглубокого знания VBA! Листбоксы сделал в целях сокращения количества кликов пользователей. Попробую с листбоксами! Спасибо! !!
 
Цитата
Сергей Иванов пишет: Я тоже верил, что WorksheetFunction в макросах - это признак неглубокого знания VBA
Всегда сумму по столбцу считаю в коде именно при помощи WorksheetFunction.Sum  :)
 
Нет, чтобы циклом, да циклом в цикле... :)
 
Да, Михаил! Все отлично работает и с листбоксами! Но как сделать так, чтобы при изменении первого листбокса изменялись списки и во втором и третьем списках одновременно? Т.е. при изменении ListBox1, ListBox2.ListIndex = 0 (т.е. ListBox2.Value = первое значение в списке), а в соответствии с этим, ListBox3.Listindex = 0? Нужно, чтобы при изменении любого листбокса все значения в листбоксах были явно определены, т.к. по связке "товар-свойство-признак" будет определяться цена. Пробовал переключать с помощью .ListIndex и/или .SetFocus - на второй-третий переклик выдает ошибку.
Какой код для этого потребуется? Прошу помощи!
Изменено: Сергей Иванов - 17.10.2014 07:35:39
 
Сильно не вчитывался :)
 
Цитата
Сергей Иванов пишет: при изменении любого листбокса
или
Цитата
при изменении первого листбокса
Изменено: Максим Зеленский - 17.10.2014 11:25:43
F1 творит чудеса
 
При изменении предыдущего листбокса меняются списки всех последующих. В нашем случае, допустим, изменили ЛБ2 - изменился ЛБ3, а ЛБ1 не изменился. Если бы были ЛБ4 и ЛБ, то и они тоже изменились бы.
"Предыдущий" и "последующий" определяются по количеству объединяемых характеристик (Товар объединяет Свойство и Признак, Свойство объединяет Признак) - чем больше, тем "первее".
 
Сергей Иванов, не жмите просто так кнопку цитирования, у нее уже синяки со всех сторон от таких пользователей :)
 
kalbasiatka, все отлично работает, но не учитывает значение из ЛБ2 при определении цены. Какой код и в каком месте нужно дописать, чтобы параметр "свойство товара" участвовал в составном имени при определении цены?
 
как-то так....
Изменено: Михаил С. - 17.10.2014 12:30:39 (Добавил вариант)
 
Михаил С., большое спасибо! И снова все работает! Но как сделать так, чтобы:
кликаю ЛБ1, получаю - ЛБ2.ListIndex = 0, ЛБ3.ListIndex = 0 и на основе ЛБ1 & ЛБ2 & ЛБ3 определяю цену для лейбла1
кликаю ЛБ2, получаю - ЛБ1 указанный пользователем перед кликом на ЛБ2, ЛБ2 - выбранное значение, ЛБ3.ListIndex = 0 и на основе ЛБ1 & ЛБ2 & ЛБ3 определяю цену для лейбла1
Т.е., смысл в следующем - каждый клик по любому ЛБ должен результатом иметь цену в лейбле1, соответствующую сочетанию ЛБ1 & ЛБ2 & ЛБ3. Сейчас в файле "Макрос Связанные списки(3)" чтобы получить цену по каждому товару, нужно кликнуть три раза. Хотелось бы один. Это возможно?
 
Цитата
Сергей Иванов пишет: Хотелось бы один. Это возможно?
Потерпите немного... Ok, Googlу уже работает, вероятно скоро и Ok, Excel будет....
 
Возможно, я плохо объясняюсь: клик по каждому листбоксу приводит все последующие листбоксы к .Listindex = 0 (так, чтобы первые значения в их списках были выделены синим), а все предыдущие сохраняют значение, выбранное пользователем ранее. Про предыдущие и последующие писал выше.
 
Если я правильно понял ваш вопрос - то добавить еще один листбокс, в котором собирать выбранные значения.
 
Михаил С., спасибо за ответ. А непосредственно на рабочем листе, в ячейках через ControlSource собирать выбранные значения - в чем отличие такого подхода от сбора в дополнительном листбоксе?
Изменено: Сергей Иванов - 21.10.2014 07:27:45
 
8 дней уже прошло ) Покажите кусок рабочего файла, а не "ТоварПризнак10000".
 
kalbasiatka, Ваш вариант от 17 Окт 2014 08:27:55 наиболее полно соответствует моим условиям. Пожалуйста, сообщите, как с Вами связаться.
 
Цитата
Сергей Иванов пишет: как с Вами связаться.
На сайте работает система личных сообщений.
Страницы: 1
Наверх