Private Sub Worksheet_Change(ByVal Target As Range) If Target.Count > 1 Or Intersect(Target, Range("K27:L34")) Is Nothing Then MsgBox "Bye!" Else MsgBox "Hi!" End If End Sub
Из кода 1-го сообщения многое непонятно. Нужна более четкая формулировка, иначе возникают варианты:
1. Target должна быть одной ячейкой
Private Sub Worksheet_Change(ByVal Target As Range) Dim i& i = Target.Count Select Case Target.Count & Target.Address(0, 0) Case "1K27" To "1K34", "1L27" To "1L34" MsgBox "Hi!" Case Else MsgBox "Bye!" End Select End Sub
2. Target должна включать хотя бы одну ячейку внутри заданного диапазона K27:L34, остальные могут быть снаружи
Private Sub Worksheet_Change(ByVal Target As Range) Select Case Target.Address(0, 0) Case "K27" To "K34", "L27" To "L34" MsgBox "Hi!" Case Else MsgBox "Bye!" End Select End Sub
3. Target может включать несколько ячеек, но все должны быть внутри заданного диапазона K27:L34
Private Sub Worksheet_Change(ByVal Target As Range) Select Case Target.Address(0, 0) & "я" Case "K27я" To "K34я", "L27я" To "L34я" MsgBox "Hi!" Case Else MsgBox "Bye!" End Select End Sub
1-й вариант правильнее так, чтобы не срабатывало еще, например, на K270
Private Sub Worksheet_Change(ByVal Target As Range) Select Case Target.Count & Target.Address(0, 0) & "я" Case "1K27я" To "1K34я", "1L27я" To "1L34я" MsgBox "Hi!" Case Else MsgBox "Bye!" End Select End Sub
if target.count>1 then exit sub select case target.row+(target.column-1)*999 case 10027 to 10034,11027 to 11034 : msgbox "hi" caseelse: msgbox "by" endselect
{quote}{login=k61}{date=22.03.2011 07:29}{thema=нужен:}{post}в Case должна быть проверка принадлежности активной ячейки диапазону K27:L34{/post}{/quote}
в таком случае и Case не нужен:
if intersect(...) then ... else ... end if
фрилансер Excel, VBA - контакты в профиле "Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
{quote}{login=k61}{date=22.03.2011 06:08}{thema=дело в том, что}{post}дело в том, что нужно отслеживать очень много адресов. If не желателен. Можно получить Строку, Столбец ячейки и их проверять в Case, но это не очень красиво.{/post}{/quote}
{quote}{login=k61}{date=22.03.2011 10:32}{thema=Re: слэн}{post}красиво. спасибо.{/post}{/quote} Красиво, только я уже отмечал, что в таком случае будет много других ячеек вне диапазона, которые выдадут такие же суммы, т.е. будут ложные срабатывания кода.
По-моему, лучше делать на базе традиционого подхода:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
Const MyRanges = "A1:B2,A3:B3,C1:D3" Dim a, i&, j&, x
a = Split(MyRanges, ",")
For Each x In a i = i + 1 If Not Intersect(Target, Range(x)) Is Nothing Then j = i: Exit For Next
Select Case j
Case 1: MsgBox a(j - 1) Case 2: MsgBox a(j - 1) Case 3: MsgBox a(j - 1)
извините, ZVI, Вы не разобрались - повторений быть не может. это аналог индексации двумерного массива, соответствующего части листа - в данном случае ограниченного тысячью строк(можно больше)
Ложных срабатываний не обнаружено. Не ожидал, что для записи в условии Case - адреса области, будут такие сложности. Век живи, век учись. Пока остановился на варианте ZVI, но как говорят одесские грузчики "таким багажом не разбрасываются! (вариант Слэна)"
{quote}{login=слэн}{date=22.03.2011 01:48}{thema=}{post}ну, в крайнем случае, поставить еще одну проверку:{/post}{/quote} либо отодвинуть неприятный момент: Select case target.row+(target.column-1)*10000 Case 100027 ......
{quote}{login=внимательный}{date=22.03.2011 01:20}{thema=Re: ikki дело в том, что}{post}{quote}{login=k61}{date=22.03.2011 06:08}{thema=дело в том, что}{post}дело в том, что нужно отслеживать очень много адресов. If не желателен. Можно получить Строку, Столбец ячейки и их проверять в Case, но это не очень красиво.{/post}{/quote}{/post}{/quote}
то, что кто-то из нас не понял другого, это да. вы для КАЖДОГО из "много адресов" хотите выполнять оператор Case? а я вам предлагаю вместо ОДНОГО оператора Case использовать ОДИН оператор if. то есть сколько там по вашему алгоритму будет Case'ов, вместо этого будет столько же if'ов. просто КАЖДЫЙ из этих if'ов будет работать (имхо!, не проверял) быстрее.
это был я. вообще, тогда хотелось бы узнать реальную задачу, а не "упростить Case" а так - что спросили, на то и ответили, т.е. упростили Case и заменили на If
фрилансер Excel, VBA - контакты в профиле "Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
Public Sub test_case() Dim r As Range, c As Range, x As Range, i As Long Set r = ActiveSheet.Range("K27:L34") Set c = ActiveSheet.Range("A1:AZ50000") t = Now i = 0 For Each x In c.Cells Select Case x.Address Case "$K$27", "$K$27", "$K$28", "$K$29", "$K$30", "$K$31", _ "$K$32", "$K$33", "$K$34", "$L$27", "$L$28", "$L$29", _ "$L$30", "$L$31", "$L$32", "$L$33", "$L$34" i = i + 1 End Select Next MsgBox Format(Now - t, "ttttt") End Sub
время работы - 26...27 сек.
Public Sub test_intersect() Dim r As Range, c As Range, x As Range, i As Long Set r = ActiveSheet.Range("K27:L34") Set c = ActiveSheet.Range("A1:AZ50000") t = Now i = 0 For Each x In c.Cells If Not Intersect(x, r) Is Nothing Then i = i + 1 Next MsgBox Format(Now - t, "ttttt") End Sub
время работы - 45...46 сек.
Public Sub test_if_and() Dim r As Range, c As Range, x As Range, i As Long Set r = ActiveSheet.Range("K27:L34") Set c = ActiveSheet.Range("A1:AZ50000") t = Now i = 0 For Each x In c.Cells If x.Row <= 34 And x.Row >= 27 And (x.Column = 11 Or x.Column = 12) Then i = i + 1 Next MsgBox Format(Now - t, "ttttt") End Sub
время работы - 15...16 сек.
пс. машинка на работе слабенькая - Celeron 2.8, RAM 256 Mb. Ex-2003.
фрилансер Excel, VBA - контакты в профиле "Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг