Как реализовать сбрасываемое, перебираемое значение ячейки по умолчанию в Excel? - PullRequest
12 голосов
/ 18 марта 2012

>> Краткое изложение вопроса

Я хочу реализовать сбрасываемое, перезагружаемое значение ячейки по умолчанию в Excel. Под этим я подразумеваю иметь ячейку, которая возвращается к значению «по умолчанию», полученному по формуле поиска, зависящей от второй ячейки, когда обновляется вторая ячейка. Кроме того, у пользователя есть возможность записать другое значение в исходную ячейку, которое будет сохраняться до следующего обновления второй ячейки.


>> Основной корпус и детали

Хорошо, вот ситуация; этот снимок относится к соответствующей области хранилища данных с несколькими листами. Две ячейки, представляющие интерес, выделены зеленым для ясности, и самая высокая видимая строка - строка 1.

  • Ячейка Поиск элемента принимает различные вводимые слова или фразы и имеет проверку данных, чтобы гарантировать, что возможны только допустимые вводы. Проверка данных берется из алфавитного списка возможных входных данных, и ячейка имеет опцию раскрывающегося списка (отсюда и маленькая стрелка справа).

  • Ячейка Stack использует входные данные из ячейки Item Search в следующей формуле ...

    =IF(COUNTIF(C3:F315,J6),VLOOKUP(J6,C3:F315,4,FALSE),"~")
    

    ... где J6 - это ячейка Поиск элемента , а диапазон C3: F315 - соответствующая часть таблицы поиска на том же листе.

    Снимок с изображением области документа Excel, относящейся к вопросу. http://img29.imageshack.us/img29/4388/capturedhx.jpg

Это то, что я хотел бы сделать в ячейке Stack ...

  • Текущая функциональность:
    • Если в ячейку Поиск элемента введен неверный ввод, вместо числа отображается тильда.
    • Когда введен правильный ввод, в ячейке отображается соответствующий номер из таблицы поиска. Ячейки Buy и Sell также обновляются таким же образом.
  • Желаемая дополнительная функциональность:
    • В первом случае тильда не может быть перезаписана.
    • Во втором случае номер «по умолчанию» можно переписать, введя другой номер в ячейку Stack .
    • Когда в ячейку Поиск элемента вводится новый ввод (или снова тот же ввод), снова отображается номер по умолчанию (или тильда).
  • Список пожеланий (необязательный):
    • Наличие флажка (или аналогичного; например, ввода да / нет в соседней ячейке), который, если отмечен галочкой, означает, что отображаемое число в ячейке Stack не будет изменено / зависит от любого нового значения по умолчанию, считываемого из таблицы поиска. Номер можно изменить, введя новый вручную.
    • В ячейке Поиск элементов в настоящее время имеется выпадающий алфавитный список всех возможных вводов данных. Есть ли способ использовать этот же список для добавления функции автозаполнения в ячейку? Возможно, немного похоже на поисковую систему Google, выпадающий список отображается при вводе, а элементы, заполняющие этот список, постоянно ограничиваются теми, которые содержат (под) строку, которую вы уже набрали.

Примечание: любое значение, отображаемое в ячейке Stack , должно читаться по формулам в других ячейках; а именно, Buy и Sell ячеек, значения которых станут отношением значения поиска в ячейке Stack к значению, отображаемому в ячейке в данный момент.

Возможно ли это в какой-то степени? Желательно (но не исключительно) без необходимости использования макросов. Эта рабочая книга предназначена для распространения среди других людей, причем большая ее часть заблокирована и защищена, чтобы избежать каких-либо изменений в основных данных.

Заранее спасибо.


Информация, найденная до сих пор:

... но не совсем решаю мой вопрос.

  1. Вероятно, я мог бы использовать более одной ячейки для достижения одинаковых (или похожих) эффективных функций (одна ячейка содержит значение по умолчанию, другая содержит возможное введенное пользователем значение, а третья содержит соответствующее выходное значение) но это не выглядело бы так хорошо и не было бы настолько интуитивно понятным для конечного пользователя. Эта рабочая книга предназначена для распространения среди других людей, большая часть которых заперта и защищена. - Этот ответ не желателен.

  2. В моих поисках в интернете, прежде чем задать этот вопрос, я обнаружил эту небольшую информацию. Он сказал, что если я хочу, чтобы возврат к значению по умолчанию был автоматическим, то используйте следующий код в подпрограмме события изменения рабочего листа:

    Private Sub Worksheet_Change(ByVal Target As Range)
        If Not Intersect(Target, Range("C2")) Is Nothing Then
            If Range("C2").Value = "" Then
                Range("C2").Value = 1234
            End If
        End If
    End Sub
    

    Однако я не до конца осознаю, что подразумевается под этим или как это сделать.
    - C2 - это номинальная ячейка, используемая в примере другого человека.

  3. Кто-то задал (возможно) аналогичный вопрос и получил этот ответ, связанный с использованием пользовательских числовых форматов. Будет ли пользовательский числовой формат принимать формулу, такую ​​как формула, используемая в настоящее время в ячейке Stack ?


Загрузка документа:

Включена текущая и требуемая функциональность, элементы списка желаний еще впереди.
Элементарный (общедоступный) .xlsm - (MediaFire)
18 марта 2012 г., 07:40 UCT

Текущая и желаемая функциональность + «Список пожеланий 1».
Элементарный (публичный) .xlsm - (Mediafire)
20 марта 2012 г., 19:50 UCT


>> РЕДАКТИРОВАТЬ # 1:

Это мой код в различных разделах:

В ThisWorkbook

Public temp As Integer 'Used to contain Range("M6").Value once CheckBox5 is ticked
Public warn As Boolean 'True if CheckBox1 is ticked whilst (vVal = "~")

Private Sub Workbook_Open()
    warn = False 'Initialise to False
End Sub

В Sheet1 (Price List)

Private Sub CheckBox1_Click()
    If OLEObjects("CheckBox1").Object.Value = True Then
        If Range("M6").Value = "~" Then
            warn = True
        Else
            temp = Range("M6").Value
            warn = False
        End If
    End If
End Sub


Private Sub Worksheet_Change(ByVal Target As Range)
    Dim vVal As Variant

    On Error GoTo Whoa

    vVal = Application.Evaluate("=IF(COUNTIF(C3:F315,J6),VLOOKUP(J6,C3:F315,4,FALSE),""~"")")

    '~~> If J6 has been changed, then continue. Otherwise skip.
    If Not Intersect(Target, Range("J6")) Is Nothing Then
        Application.EnableEvents = False
        ActiveSheet.Unprotect ("012370asdf")

        If vVal = "~" Then
            Range("M6").Value = "~"
            Range("M6:M7").Locked = True
        Else
            '~~> Check if CheckBox5 is ticked.
            If OLEObjects("CheckBox5").Object.Value = True Then
                '~~> Checks if CheckBox5 was ticked whilst (vVal = "~")
                If warn = True Then
                    temp = vVal
                    warn = False 'Reset warn status now that special case is resolved
                End If
                Range("M6").Value = temp
            Else
                Range("M6").Value = vVal
            End If
            Range("M6:M7").Locked = False
        End If

        ActiveSheet.Protect ("012370asdf")
        GoTo LetsContinue
    End If

    '~~> If M6 has been changed, then continue. Otherwise skip.
    If Not Intersect(Target, Range("M6")) Is Nothing Then
        Application.EnableEvents = False

        If OLEObjects("CheckBox5").Object.Value = True Then
            temp = Range("M6").Value
        End If

        GoTo LetsContinue
    End If

LetsContinue:
    Application.EnableEvents = True
    Exit Sub
Whoa:
    MsgBox err.Description
    Resume LetsContinue
End Sub

Этот код еще не включает 'Список пожеланий 2' , но в остальном работает нормально.

Большое спасибо тем, кто помог.

Ответы [ 2 ]

7 голосов
/ 18 марта 2012

@ SiddharthRout: Я все равно буду загружать текущую копию файла для вашего ознакомления. На части моего вопроса ответили, но в моем «Списке желаний» еще есть два пункта, с которыми еще предстоит покончить! -

Согласно моему более раннему предложению текущий код, который вы используете, должен быть записан как

Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo Whoa

    If Not Intersect(Target, Range("J6")) Is Nothing Then
        Application.EnableEvents = False
        ActiveSheet.Unprotect ("012370asdf")
        If Application.Evaluate("=IF(COUNTIF(C3:F315,J6),VLOOKUP(J6,C3:F315,4,FALSE),""~"")") = "~" Then
            Range("M6").Value = "~"
            Range("M6:M7").Locked = True
        Else
            Range("M6").Formula = "=IF(COUNTIF(C3:F315,J6),VLOOKUP(J6,C3:F315,4,FALSE),""~"")"
            Range("M6:M7").Locked = False
        End If
        ActiveSheet.Protect ("012370asdf")
    End If

LetsContinue:
    Application.EnableEvents = True
    Exit Sub
Whoa:
    MsgBox Err.Description
    Resume LetsContinue
End Sub

Это также сводит на нет использование дополнительной ячейки N6.

Сейчас я смотрю на все остальное и скоро обновлю.

ОБНОВЛЕНИЕ : Оба ваших запроса в WishList выполнены.

Ваше событие Worksheet_Change теперь становится таким, чтобы включить Список желаний 1 ( См. Прикрепленный снимок )

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim vVal As Variant

    On Error GoTo Whoa

    vVal = Application.Evaluate("=IF(COUNTIF(C3:F315,J6),VLOOKUP(J6,C3:F315,4,FALSE),""~"")")

    If Not Intersect(Target, Range("J6")) Is Nothing Then
        Application.EnableEvents = False

        ActiveSheet.Unprotect ("012370asdf")

        '~~> Check the value of the CheckBox and update cells only if false
        '~~> This is valid for "~" as well i.e if the checkbox is Checked then
        '~~> even "~" remain unchanged. If you don't want this, then move the 
        '~~> below condition inside "ELSE" part :)
        If OLEObjects("Checkbox1").Object.Value = False Then
            If vVal = "~" Then
                Range("M6").Value = "~"
                Range("M6:M7").Locked = True
            Else
                Range("M6").Value = vVal
                Range("M6:M7").Locked = False
            End If
        End If

        ActiveSheet.Protect ("012370asdf")
    End If

LetsContinue:
    Application.EnableEvents = True
    Exit Sub
Whoa:
    MsgBox Err.Description
    Resume LetsContinue
End Sub

Для вашего второго списка желаний у меня было два варианта. Я выбрал второй вариант.

1) Используйте метод, описанный в www.ozgrid.com

Тема: Автозаполнение набора в списке проверки данных Excel

Ссылка : http://www.ozgrid.com/Excel/autocomplete-validation.htm

И

2) Используйте элемент управления вместо списка DV. Для этого я внес эти изменения в список

  • Удалить проверку данных в ячейке J6
  • дал "Имя" вашему списку X3: X315 из Диспетчер имен . Я назвал это "Список"
  • Поместите ComboBox поверх ячейки J6 и установите .ListFillRange в вышеприведенный «Список» в режиме конструктора
  • Добавлен следующий код в область кода листа

КОД

Private Sub ComboBox1_Click()
    Range("J6").Value = ComboBox1.Value
End Sub

Private Sub ComboBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, _
ByVal Shift As Integer)
    If KeyCode = 13 Then
        Range("J6").Value = ComboBox1.Value
    End If
End Sub`

Теперь ваш ComboBox будет автоматически заполняться всякий раз, когда вы вводите что-либо в поле.

СНАПШОТ

enter image description here

SAMPLE FILE LINK (эта ссылка активна в течение 7 дней)

Пример файла

НТН

Sid

2 голосов
/ 18 марта 2012

Я сейчас не за компьютером, поэтому не могу проверить это, но вот что вам нужно сделать:

Номер 2 в вашей «Информации, найденной до сих пор» - верное направление, даже если вы сказали, что вам не нужны макросы.

Переместите формулу для ячейки Stack в другую ячейку, которая не используется. Заблокируйте эту ячейку и установите одинаковые цвета фона и текста (чтобы они были «скрыты»). А пока скажем, что это в О6. (Или просто поместите эту ячейку на другой лист, к которому они не могут получить доступ. У меня часто есть скрытый лист только для них.)

Щелкните правой кнопкой мыши вкладку листа и выберите View Code. В новом окне дважды щелкните имя листа, на котором вы хотите запустить этот код.

Private Sub Worksheet_Change(ByVal Target As Range) должна быть функцией по умолчанию, которая появляется (и она будет пустой).

Поместите следующий код в процедуру Worksheet_Change:

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim rng As Range
    Set rng = Intersect(Range("J6"), Target)

    'If J6 has not been changed, then exit.  Otherwise continue.
    If rng Is Nothing Then
        Exit Sub
    Else
        'Replace password with the password that you use to protect the sheet (two places)
        ActiveSheet.Unprotect ("password")
        If Range("O6").Value = "~" Then
            Range("M6").Value = "~"
            Range("M6:M7").Locked = True
        Else
            Range("M6").Value = Range("O6").Value
            'Use M6:M7 here instead of just M6 because cells are merged.
            Range("M6:M7").Locked = False
        End If 
        ActiveSheet.Protect ("password")
    End If
End Sub
...