Да, для этого можно использовать VBA. Однако именованные диапазоны возможны только в том случае, если вы собираетесь использовать страны и города как непрерывный список, то есть все строки, отсортированные по странам и городам в указанном порядке. Приведенный ниже код позволит вам создать эту функцию независимо от порядка сортировки, т. Е. Даже если данные не отсортированы. Это основной код, написанный не для производительности, но работающий, пожалуйста, отредактируйте его соответствующим образом. Надеюсь, что это решит вашу проблему.
Sub SetupCountry() 'run this on workbook open event
Dim rng As Range
Set rng = ActiveSheet.Range("H7") 'choose your cell(s) here
With rng.Validation
FRM = GetUniqueCountries()
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:=FRM
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
End Sub
Sub SetupCity() 'run this sub on the change event of Country cell
Dim rng As Range
Set rng = ActiveSheet.Range("I7") 'choose your cell(s) here
With rng.Validation
FRM = GetCities()
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:=FRM
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
End Sub
Function GetUniqueCountries() As String
Dim sOut As String
Dim v, c
Dim rngList As Range
Set rngList = ActiveSheet.Range("D7:D28") 'edit the range where your country list is stored
sOut = ""
For Each c In rngList
If InStr(1, sOut, c.Value & ",") = 0 Then 'check if the value is already in the upload list and add if not there
sOut = c.Value & "," & sOut
End If
Next c
'remove first ,
If sOut <> "" Then
sOut = Left(sOut, Len(sOut) - 1)
End If
GetUniqueCountries = sOut
End Function
Function GetCities() As String
Dim sOut As String
Dim v, c
Dim rngSearch As Range
Set rngSearch = ActiveSheet.Range("D7:D28") 'edit the range where your cities list exists
sOut = ""
For Each c In rngSearch
If c.Value = ActiveSheet.Range("H7").Value Then 'selected country
sOut = sOut & "," & ActiveSheet.Range("E" & c.Row).Value
End If
Next c
'remove first ,
If sOut <> "" Then
sOut = Mid(sOut, 2)
End If
GetCities = sOut
End Function
Если вы в порядке, сортируя данные по стране и городам, то именованные диапазоны будут более элегантным решением. Где тогда формула подтверждения данных для города будет ссылаться на именованный диапазон, например CITIES вам нужно будет сбросить диапазон для CITIES на основе значения страны (используя аналогичную конструкцию функции getCities ().
. Один простой способ изменить ссылку на диапазон для именованного диапазона показан ниже. Формула может быть обновлено на основе результатов поиска.
ActiveWorkbook.Names("SOMENAMEDRANGE").RefersTo = "=Sheet1!$D$5:$L$25"
Существует больше проблем, чем просто начальный символ подчеркивания, я боюсь.
Когда Вы звоните my_function()
, это все еще не будет иметь Вашего debug
переменная в ее пространстве имен, если Вы не импортируете его из two.py
.
Конечно, выполнение, которое означает, что Вы закончите с циклическими зависимостями (one.py -> two.py -> one.py
), и Вы доберетесь NameError
s, если Вы не осуществляете рефакторинг, куда различные вещи импортируются и объявляются.
Одно решение состояло бы в том, чтобы создать простой третий модуль, который определяет 'константы' как это, которое может быть безопасно импортировано отовсюду, например:
constants.py
------------
debug = True
one.py
------
from constants import debug
#...
two.py
------
from constants import debug
#...
Однако я рекомендовал бы просто использовать созданный в регистрирующемся модуле для этого - почему нет? Легко настроить, более простой использовать, надежный, гибкий и расширяемый.
Можно также использовать __debug__
переменная для отладки. Это верно, если интерпретатор не был запущен с-O опции. Оператор контроля мог бы быть полезным, также.
Имена, начинающиеся с подчеркивания, не импортируются с
from one import *
Немного больше объяснения: функция my_function
пространство имен всегда находится в модуле one
. Это означает это когда имя _debug
не найден в my_function
, это заглядывает one
, не пространство имен, от которого вызвана функция. Ответ алебастра предоставляет хорошее решение.