Добрый день! И вновь два больших массива Пытаюсь в столбец R подставить максимальное значение номера квартиры из M:N Формула массива
Код
=МАКС((Q2=$M$2:$M$64)*$N$2:$N$64)
адекватно работает на небольшом количестве строк. Пытаюсь мучить словари, но без опыта и с минимумом знаний все медленно катится в пропасть Методом плагиата и подгона получил следующее [vba]
Код
Sub МинМакс() Application.ScreenUpdating = 0 Application.Calculation = 3 r0_ = 2 ' n1_ = Cells(Rows.Count, 13).End(3).Row - r0_ + 1 n2_ = Cells(Rows.Count, 17).End(3).Row - r0_ + 1 Cells(r0_, 18).Clear ar1 = Cells(r0_, 13).Resize(n1_, 2) ar2 = Cells(r0_, 17) Set slov = CreateObject("Scripting.Dictionary") With slov For i = 1 To n2_ .Item(ar2(i, 1)) = i Next i For j = 1 To n1_ If .exists(ar1(j, 1)) Then s_ = .Item(ar1(j, 1)) For k = 2 To 2 ar1(j, k) = ar2(s_, k) Next k End If Next j End With Cells(r0_, 18) = ar1 Application.Calculation = 1 Application.ScreenUpdating = 1 End Sub
[/vba] но, во-первых он ругается на[vba]
Код
.Item(ar2(i, 1)) = i
[/vba] а, во-вторых, я как-то совсем не понимаю как заставить искать максимум, да еще и с условием совпадений элементов в столбце M со столбцом Q игнорируя ячейки, где содержатся ЛЮБЫЕ не цифры (дроби, пробелы, слеши, буквы и тд)
Добрый день! И вновь два больших массива Пытаюсь в столбец R подставить максимальное значение номера квартиры из M:N Формула массива
Код
=МАКС((Q2=$M$2:$M$64)*$N$2:$N$64)
адекватно работает на небольшом количестве строк. Пытаюсь мучить словари, но без опыта и с минимумом знаний все медленно катится в пропасть Методом плагиата и подгона получил следующее [vba]
Код
Sub МинМакс() Application.ScreenUpdating = 0 Application.Calculation = 3 r0_ = 2 ' n1_ = Cells(Rows.Count, 13).End(3).Row - r0_ + 1 n2_ = Cells(Rows.Count, 17).End(3).Row - r0_ + 1 Cells(r0_, 18).Clear ar1 = Cells(r0_, 13).Resize(n1_, 2) ar2 = Cells(r0_, 17) Set slov = CreateObject("Scripting.Dictionary") With slov For i = 1 To n2_ .Item(ar2(i, 1)) = i Next i For j = 1 To n1_ If .exists(ar1(j, 1)) Then s_ = .Item(ar1(j, 1)) For k = 2 To 2 ar1(j, k) = ar2(s_, k) Next k End If Next j End With Cells(r0_, 18) = ar1 Application.Calculation = 1 Application.ScreenUpdating = 1 End Sub
[/vba] но, во-первых он ругается на[vba]
Код
.Item(ar2(i, 1)) = i
[/vba] а, во-вторых, я как-то совсем не понимаю как заставить искать максимум, да еще и с условием совпадений элементов в столбце M со столбцом Q игнорируя ячейки, где содержатся ЛЮБЫЕ не цифры (дроби, пробелы, слеши, буквы и тд)AVI
Да, вы правы. Написал какую-то ерунду. Мне нужно найти и отобразить в столбец R максимальное значение из столбца N при условии сопадения адресов в столбце Q со столбцом M
Да, вы правы. Написал какую-то ерунду. Мне нужно найти и отобразить в столбец R максимальное значение из столбца N при условии сопадения адресов в столбце Q со столбцом MAVI
Sub tt() nM_ = Cells(Rows.Count, "M").End(3).Row - 1 nQ_ = Cells(Rows.Count, "Q").End(3).Row - 1 arM = Cells(2, "M").Resize(nM_, 2) arQ = Cells(2, "Q").Resize(nQ_) Set slovQ = CreateObject("Scripting.Dictionary") With slovQ For i = 1 To nQ_ aaa = .Item(arQ(i, 1)) Next i For j = 1 To nM_ If .exists(arM(j, 1)) Then If IsNumeric(arM(j, 2)) Then If .Item(arM(j, 1)) < arM(j, 2) Then .Item(arM(j, 1)) = arM(j, 2) End If End If End If Next j Cells(2, "R").Resize(nQ_) = Application.Transpose(.Items) End With End Sub
[/vba]
Вашу формулу можно вот так переписать
Код
=МАКС(ЕСЛИ(Q2=$M$2:$M$64;$N$2:$N$64))
А макрос, как вариант, вот так [vba]
Код
Sub tt() nM_ = Cells(Rows.Count, "M").End(3).Row - 1 nQ_ = Cells(Rows.Count, "Q").End(3).Row - 1 arM = Cells(2, "M").Resize(nM_, 2) arQ = Cells(2, "Q").Resize(nQ_) Set slovQ = CreateObject("Scripting.Dictionary") With slovQ For i = 1 To nQ_ aaa = .Item(arQ(i, 1)) Next i For j = 1 To nM_ If .exists(arM(j, 1)) Then If IsNumeric(arM(j, 2)) Then If .Item(arM(j, 1)) < arM(j, 2) Then .Item(arM(j, 1)) = arM(j, 2) End If End If End If Next j Cells(2, "R").Resize(nQ_) = Application.Transpose(.Items) End With End Sub
_Boroda_, Блин, я в шоке ваще... Раньше я просто уходил на полчаса от компа, когда формулой это искал... Щас успел моргуть глазом полтора раза и готово. Это просто какое-то волшебство - словари. Нашел обучалки по словарям. Пробую освоить.
А как получается, что оно максимальное ищет?
_Boroda_, Блин, я в шоке ваще... Раньше я просто уходил на полчаса от компа, когда формулой это искал... Щас успел моргуть глазом полтора раза и готово. Это просто какое-то волшебство - словари. Нашел обучалки по словарям. Пробую освоить.
_Boroda_, Добавил и выделил красным. Нужно, что бы максимум определялся только между целыми числами. Ячейки, содержащие все, что не есть целое число: пробелы, запятые, дроби, точки, буквы и прочие символы (это, кончено в идеале) - игнорировались, но если это трудоемко, то будет достаточно игнорировать Istext + Chr(160) + Chr(044). Я знаю как find'ом искать это, но это существенно скажется на скорости работы макроса.
_Boroda_, Добавил и выделил красным. Нужно, что бы максимум определялся только между целыми числами. Ячейки, содержащие все, что не есть целое число: пробелы, запятые, дроби, точки, буквы и прочие символы (это, кончено в идеале) - игнорировались, но если это трудоемко, то будет достаточно игнорировать Istext + Chr(160) + Chr(044). Я знаю как find'ом искать это, но это существенно скажется на скорости работы макроса.AVI
If IsNumeric(arM(j, 2)) And Instr(1,arM(j, 2),",",vbTextCompare)=0 And Instr(1,arM(j, 2),".",vbTextCompare)=0 Then
StoTisteg, вы когда уже будете проверять то, что советуете? Такой вариант [vba]
Код
Sub tt() nM_ = Cells(Rows.Count, "M").End(3).Row - 1 nQ_ = Cells(Rows.Count, "Q").End(3).Row - 1 arM = Cells(2, "M").Resize(nM_, 2) arQ = Cells(2, "Q").Resize(nQ_) Set slovQ = CreateObject("Scripting.Dictionary") With slovQ For i = 1 To nQ_ aaa = .Item(arQ(i, 1)) Next i For j = 1 To nM_ If .exists(arM(j, 1)) Then If IsNumeric(arM(j, 2)) Then If CStr(CInt(arM(j, 2))) = arM(j, 2) Then If .Item(arM(j, 1)) < arM(j, 2) Then .Item(arM(j, 1)) = arM(j, 2) hhh = .Item(arM(j, 1)) End If End If End If End If Next j Cells(2, "R").Resize(nQ_) = Application.Transpose(.Items) End With End Sub
[/vba] Можно еще, например, проверять регэкспом наличие только чисел, но да ладно
If IsNumeric(arM(j, 2)) And Instr(1,arM(j, 2),",",vbTextCompare)=0 And Instr(1,arM(j, 2),".",vbTextCompare)=0 Then
StoTisteg, вы когда уже будете проверять то, что советуете? Такой вариант [vba]
Код
Sub tt() nM_ = Cells(Rows.Count, "M").End(3).Row - 1 nQ_ = Cells(Rows.Count, "Q").End(3).Row - 1 arM = Cells(2, "M").Resize(nM_, 2) arQ = Cells(2, "Q").Resize(nQ_) Set slovQ = CreateObject("Scripting.Dictionary") With slovQ For i = 1 To nQ_ aaa = .Item(arQ(i, 1)) Next i For j = 1 To nM_ If .exists(arM(j, 1)) Then If IsNumeric(arM(j, 2)) Then If CStr(CInt(arM(j, 2))) = arM(j, 2) Then If .Item(arM(j, 1)) < arM(j, 2) Then .Item(arM(j, 1)) = arM(j, 2) hhh = .Item(arM(j, 1)) End If End If End If End If Next j Cells(2, "R").Resize(nQ_) = Application.Transpose(.Items) End With End Sub
[/vba] Можно еще, например, проверять регэкспом наличие только чисел, но да ладно_Boroda_
_Boroda_, я, уж, не знаю как просить, но, если значение с пробелом поменять, например, на 999 949 то вылезает ошибка overflow и ругается на строку [vba]
Код
If CStr(CInt(arM(j, 2))) = arM(j, 2) Then
[/vba] Что-то мне подсказывает, что дело в переменной. Может поставить тип long?
_Boroda_, я, уж, не знаю как просить, но, если значение с пробелом поменять, например, на 999 949 то вылезает ошибка overflow и ругается на строку [vba]
Код
If CStr(CInt(arM(j, 2))) = arM(j, 2) Then
[/vba] Что-то мне подсказывает, что дело в переменной. Может поставить тип long?AVI
Вы поменяли не на 999 949, а на 999494 и поставили числовой формат с разделителями разрядов. Это разные вещи - 999494 вполне нормальный номер квартиры А вот если Вы поставите в текстовом формате 999 949, то это другое дело
И замените CInt на CLng (надеюсь, чисел, больших 2 147 483 647, не предвидится?)
* Добавлено Вы уже и сами догадались. Но на формат обратите внимание
Вы поменяли не на 999 949, а на 999494 и поставили числовой формат с разделителями разрядов. Это разные вещи - 999494 вполне нормальный номер квартиры А вот если Вы поставите в текстовом формате 999 949, то это другое дело
И замените CInt на CLng (надеюсь, чисел, больших 2 147 483 647, не предвидится?)
* Добавлено Вы уже и сами догадались. Но на формат обратите внимание_Boroda_