Страницы: 1 2 След.
RSS
Удаление из Listbox с Multiselect
 
Всем доброго времени суток.

Не могу побороть удаление из листбокса нескольких пунктов одновременно.
Мультиселект = 1
Чего я хочу добиться:
При выделении нескольких пунктов в листбоксе циклом проверяя, что Listbox1.selected(i) = true надо удалять соответствующую строку на листе "info_list", а потом необходимо обновить данные в Листбоксе из Листа "info_list", где удалялась строка.
Если строку не удаляю, а только проверяю, что она выделена, то выделение считывается в сообщение, но сбиваются листиндексы почему-то, например, на две выделенных строки в Листбоксе показывает одинаковый Листиндекс.

Посмотрите, пожалуйста, файл. Может кто-то знает в чем проблема?

PS: Причем одну строку удаляет.
Иногда только промахнувшись, понимаешь как ты попал.
 
Из справки
Цитата
If you use the MultiSelect property to create a ListBox that allows multiple selections, the Selected property of the ListBox (rather than the ListIndex property) identifies the selected rows. The Selected property is an array with the same number of values as the number of rows in the ListBox. For each row in the list box, Selected is True if the row is selected and False if it is not. In a ListBox that allows multiple selections, ListIndex returns the index of the row that has focus, regardless of whether that row is currently selected.
Как я поняла при MultiSelect - ListIndex показывает номер того элемента на котором фокус
Например сейчас фокус на Котове на картинке (ListIndex = 1)


В остальном у вас вроде всё нормально.
Изменено: Leanna - 28.02.2015 01:17:02
Работать надо не 12 часов, а головой.
 
Цитата
 Note
If you use the MultiSelect property to create a ListBox that allows multiple selections, the Selected property of the ListBox (rather than the ListIndex property) identifies the selected rows. The Selected property is an array with the same number of values as the number of rows in the ListBox. For each row in the list box, Selected is True if the row is selected and False if it is not. In a ListBox that allows multiple selections, ListIndex returns the index of the row that has focus, regardless of whether that row is currently selected.
 
Не заметил этого, спасибо, но тем не менее, если раскомментировать строку
ThisWorkbook.Worksheets("info_list";).Rows(i + 2).Delete Shift:=xlUp,
и выбрать более одного пункта в Листбоксе, то макрос не удалит на листе более одного выбранного пункта. Почему???
Иногда только промахнувшись, понимаешь как ты попал.
 
Если бы Вы прошли программу по шагам (F8), то увидели бы, что после удаления строки все строки в листбоксе оказываются невыбранными! Потому что у него меняется .RowSource.
Значит надо формировать диапазон на удаление, а потом удалять его после цикла.
 
Я проверял и видел, что слетает диапазон, но думал, что есть более простое решение, которого я не знаю.
Спасибо за совет
Иногда только промахнувшись, понимаешь как ты попал.
 
Казанский, RowSorce не меняется после удаления (по крайней мере в моих опытах). Может что-то другое?
А почему все строки оказываются не выбранными - для меня загадка.
Работать надо не 12 часов, а головой.
 
Я сам еще не понял до конца, но уже создал диапазон и тестирую удаление. Если получится выложу. Может кто-то еще дельное подскажет.
Иногда только промахнувшись, понимаешь как ты попал.
 
1. не применяй     в таком случае RowSource
Надёжней      
Код
  UserForm1.ListBox1.List = ThisWorkbook.Worksheets("info_list";).Range(Cells(2, 1), Cells(iLastRow, iLastCol)).Value

2. удаляй сразу строку и на листе и в списке

Код
        If ListBox1.Selected(i) = True Then
            DelData = DelData & ThisWorkbook.Worksheets("info_list";).Cells(i + 2, 1).Value & Chr(13) & Chr(10)
            ThisWorkbook.Worksheets("info_list";).Rows(i + 2).Delete Shift:=xlUp 'Select
            ListBox1.RemoveItem (i)
            MsgBox i
        End If
Изменено: Александр Моторин - 28.02.2015 01:46:12
 
Проблема в том, что при выборе RowSourse я могу затянуть в Листбокс названия колонок, а при этом варианте нет. Надо делать Label's
Иногда только промахнувшись, понимаешь как ты попал.
 
Немного доработал, но глюки есть.
Может у кого-то есть идеи. Помогите, добить этот MultiSelect!!!!!!!!!
Иногда только промахнувшись, понимаешь как ты попал.
 
Основные ошибки подправил.
Идея ясна! Надо доработать и оптимизировать.
А так вполне рабочая версия. Добавить еще обработку ошибок, когда удаляешь последние строки и все.
Иногда только промахнувшись, понимаешь как ты попал.
 
Обработал ошибки, теперь работает без сбоев.
Хотелось бы оптимизировать.
Может у кого-то будет мнение на этот счет?
Надеюсь кто-то даст интересный совет.
Иногда только промахнувшись, понимаешь как ты попал.
 
1. Совсем необязательно активировать лист.
2. При отсутствии выбранных позиций срабатывает MsgBox с сообщением, что удалены все данные. А такого быть не должно)
 
Юрий, добрый день.
Сообщение мое, поэтому оно всплывает принудительно. Без него тоже все работает, проверил.
А если не активирую лист не хочет работать ,т.к. запускаю вывод через RowSource. Обойти не получается. Видимо это плата за получение названия колонок в ЛистБокс )))
Иногда только промахнувшись, понимаешь как ты попал.
 
Не понял сразу за какое сообщение вы сказали, да есть такая недоработка. Устраню. Спасибо!
Иногда только промахнувшись, понимаешь как ты попал.
 
Здравствуйте! Попробуйте использовать конструкцию With sheets(ИмяЛиста) - end with
И ещё один момент: зачем вычислять номер последнего столбца, если их количество известно заранее?
 
Мне кажется, что можно сделать компактнее, понятнее и быстрее)) Алгоритм следующий:
1. Циклом бежим по ЛистБоксу - если НЕ выбрано, то забираем строку в массив.
2. На листе с исходными данными очищаем диапазон, сбрасываем массив на лист.
3. ЛистБоксу скармливаем тот же массив.
RowSource не нужен.
 
Ошибки с сообщениями подправил. Все теперь правильно. Конструкцию с With sheets обязательно добавлю, не успел еще, а последний столбец вычисляю, т.к. это кусок программы. Количество строк и столбцов будет меняться.
Иногда только промахнувшись, понимаешь как ты попал.
 
См. #18
 
Цитата
Юрий М написал:
1. Циклом бежим по ЛистБоксу - если НЕ выбрано, то забираем строку в массив.
2. На листе с исходными данными очищаем диапазон, сбрасываем массив на лист.
3. ЛистБоксу скармливаем тот же массив.
Юрий, идея лучшая! С этого я и начинал, но у меня не получилось. С массивами небольшая беда пока еще ))) Учусь. Сделал как смог, если кто-то подскажет или покажет как с массивами - буду очень благодарен! Может Вас не затруднит?
Иногда только промахнувшись, понимаешь как ты попал.
 
Вижу, Алексей в теме - может у него есть вариант получше? ))
 
"Гуры", вам труда не стоит, а мне один урок - решение!
Ну будьте же так любезны...Подскажите про массивы)))
Иногда только промахнувшись, понимаешь как ты попал.
 
Вот сделал пока инициализацию - посмотрите, как там с массивом работа. Этот же фрагмент пригодится Вам и на завершающем этапе предложенного мною алгоритма. Дальше писать просто нет сейчас времени. Попробуйте перебором забрать в новый массив данные самостоятельно. Если не получится, и никто не подключится - сделаю вечером.
 
См. файл. Третий лист можно удалить - из него копировал данные при отладке.
Исправил файл.
 
Спасибо, Юрий.
Я только вернулся. Сейчас посмотрю.
Иногда только промахнувшись, понимаешь как ты попал.
 
Тестировал.
Если в Листбоксе 4 позиции и выделяю удалить две крайние, например - сначала удаляются, затем выделяю две последние - не удаляются, если одну из них выделяю - удаляет одну, но последнюю не хочет никак. Пытаюсь разобраться в вашем коде, но мне сложновато пока. Если можно, посмотрите еще разок.
И вопрос по поводу заголовков столбцов - нужно вставлять Label над Листбоксом над столбцами?
Иногда только промахнувшись, понимаешь как ты попал.
 
Не думал, что потребуется пустой ЛистБокс). Добавьте так:
Код
With Sheets("info_list")
        LastRow = .Cells(Rows.Count, 1).End(xlUp).Row
        LastCol = .Cells(1, Columns.Count).End(xlToLeft).Column
        If LastRow = 2 Then
            .Range(.Cells(2, 1), .Cells(LastRow + 1, LastCol + 1)).ClearContents
            Me.ListBox1.Clear
            Exit Sub
        End If
    End With



 
Юрий, спасибо вам большое.
Я разберусь в коде. Уверен, мне это очень поможет в дальнейшем.
Спасибо!
Иногда только промахнувшись, понимаешь как ты попал.
 
Наверное, есть смысл ещё упростить/укоротить: не перекладывать из массива в массив, а  после того, как выгрузили массив на лист, определить LastRow, забрать диапазон в массив и подсунуть ЛистБоксу))
Страницы: 1 2 След.
Наверх