Страницы: 1
RSS
Накопление значений в ячейке. Как избежать удаления записей из выпадающего списка
 
Коллеги, подскажите пожалуйста, сделала по примеру выпадающий список с накоплением.

Если поочередно выбирать данные выпадающем списке, то они через точку с запятой перечисляются в ячейке.
А как прописать так, если выбираешь то значение которое уже есть в ячейке, то оно из ячейки удаляется.
То есть если ты выбираешь то значение, которое было выбрано раньше, то оно удаляется из ячейки.
Код
Private Sub Worksheet_Change(ByVal Target As Range)
    On Error Resume Next
    If Not Intersect(Target, Range("C15:C18")) Is Nothing And Target.Cells.Count = 1 Then
        Application.EnableEvents = False
        newVal = Target
        Application.Undo
        oldval = Target
        If Len(oldval) <> 0 And oldval <> newVal Then
            Target = Target & ";" & newVal
        Else
            Target = newVal
        End If
        If Len(newVal) = 0 Then Target.ClearContents
        Application.EnableEvents = True
    End If
End Sub
Пример во вложении. Макрос на Лист2 (Лист1), лист самый первый. желтым выделена ячейка для примера.
 
Цитата
что никто???(((
Вашим коллегам, видимо, понятно не очень много  из того, что написано в макросе и, соответственно, как его изменить...
скопируйте вот это
Код
Private Sub Worksheet_Change(ByVal rg As Range)
  Dim Nv, Ov, Lv
  If Intersect(rg, Range("C15:C18")) Is Nothing Or rg.Count > 1 Then Exit Sub
  If Len(rg) = 0 Then Exit Sub
  Application.EnableEvents = False:  Nv = rg:  Application.Undo:  Ov = rg
  If Ov = Nv Then rg = "": Application.EnableEvents = True: Exit Sub
  If Len(Ov) = 0 Then
    rg = Nv
  Else
    Lv = NvInOv(CStr(Nv), Ov): If Lv = False Then rg = rg & ";" & Nv Else rg = Lv
  End If
  Application.EnableEvents = True
End Sub


Function NvInOv(Nv$, Ov)
  Dim v, i&
  v = Split(Ov, ";"): NvInOv = False
  For i = LBound(v) To UBound(v)
    If v(i) = Nv Then
      v(i) = Empty: NvInOv = Replace(Join(v, ";"), ";;", ";"): v = Split(NvInOv, ";")
      If v(UBound(v)) = "" Then NvInOv = Left(NvInOv, Len(NvInOv) - 1)
      If Left(NvInOv, 1) = ";" Then NvInOv = Right(NvInOv, Len(NvInOv) - 1)
      Exit Function
    End If
  Next
End Function

в модуль листа, удалите или закомментируйте Вашу Private Sub Worksheet_Change

Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Ігор Гончаренко,пасибо большое!
Все работает! То, что нужно было.

Огромное спасибо)))
 
Код
Private Sub Worksheet_Change(ByVal Target As Range)
Dim newVal As String, oldval As String
    If Target.Cells.Count > 1 Then Exit Sub

    If Not Intersect(Target, Range("C15:C18")) Is Nothing Then
        Application.EnableEvents = False
        
        With Target
            newVal = .Value: Application.Undo: oldval = .Value
        
            If oldval Like "*" & newVal & "*" Then
                oldval = Replace(Replace(oldval, newVal, ""), ";;", ";")
                If Right$(oldval, 1) = ";" Then oldval = Left$(oldval, Len(oldval) - 1)
                .Value = oldval
            Else
                .Value = .Value & ";" & newVal
            End If
            
            If Left$(.Value, 1) = ";" Then .Value = Mid$(.Value, 2)
        End With
        
        Application.EnableEvents = True
    End If
End Sub
 
Виктор,  
а как быть с такими списками допустимых значений:
1;6;11
или
сад;садист
в первом из случаев выбираем из списка 11, а затем выбираем 1 и что получим в итоге вместо ожидаемых 11;1?
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Цитата
Ігор Гончаренко написал: а как быть с такими списками
Делить Split'ом в отдельной функции :)
 
Цитата
Ігор Гончаренко написал:
а как быть с такими списками допустимых значений:
1;6;11
или
сад;садист
Цитата
vikttur написал:
Делить Split'ом в отдельной функции

а можно еще вот так :)
вместо▼
Код
...
If oldval Like "*" & newVal & "*" Then                
oldval = Replace(Replace(oldval, newVal, ""), ";;", ";")
...
записать▼
Код
...
If ";" & oldval & ";" Like "*;" & newVal & ";*" Then                
oldval = Replace(";" & oldval & ";", ";" & newVal & ";", ";")
oldval = Mid(oldval, 2, Len(oldval) - 2)
...
Всё сложное - не нужно. Всё нужное - просто /М. Т. Калашников/
 
Цитата
Lilo_255 написал:
если ты выбираешь то значение, которое было выбрано раньше, то оно удаляется из ячейки
А если по ошибке выбрал второй раз нужное значение? :) Я бы поставил "защиту от дурака"
Всё сложное - не нужно. Всё нужное - просто /М. Т. Калашников/
 
Цитата
а можно еще вот так...
If ";" & oldval & ";" Like "*;" & newVal & ";*" Then  
Можно. Попробовал вчера, забросил. Нужно добавлять проверки: сдвоенные ;;,  отсутствие таковых. Со Split правильнее.
 
Всем огромное спасибо))
 
Скажите, а как заставить данный макрос работать по всей книге, у меня в файле много одинаковых листов. Что нужно изменить. Спасибо
 
Поищите, как открывать книгу и брать из нее данные. Потом - как организовать цикл для открытия нескольких книг. После этого соедините три макроса в один.
Или создавайте темы, соблюдая правила: один вопрос - одна тема
Или создайте заказ в разделе платных заказов
Страницы: 1
Наверх