Страницы: 1
RSS
В выделенном диапазоне в формулах ссылки на диапазоны изменить на массивы, vba
 
Здравствуйте
В Excel при активной формуле в ячейке выделенную часть ссылки можно изменить в постоянный массив клавишей F9.
Например, в файле формула =ВПР(D8;$L$8:$M$12;2;) при выделении  $L$8:$M$12 и использовании F9 преобразится в =ВПР(D8;{"a";1:"b";2:"c";3:0;0:0;0};2;) .
Как макросом в выделенных столбцах(в файле E:G) во всех формулах изменить все ссылки в постоянный массив?
В ячейке E5 формула уже преобразована.
Изменено: БМВ - 18.03.2024 09:52:48
 
Оговорки
1. если будет выделен столбец, то будет засада.
2. Если в диапазоне много значений и итоговая длинна массива большая то нужно придумывать еще и это  обрабатывать при замене.
3. если будет не только ссылка, но и похожий текст, то будет замена ложная
4. закрепления областей - я сделал в примере только перебор 4х вариантов, а их 8 и еще не учитывается ссылка на другой лист, хотя это можно доработать. На другую книгу (что сложнее ведь она может быть закрытой).
5. Я только концепт предложил, это не финишное решение.

Скрытый текст
Изменено: БМВ - 19.03.2024 21:31:37
По вопросам из тем форума, личку не читаю.
 
Только сей час заметил что есть решение в теме.
Макрос да, отработал на примере. Большое спасибо! Однако не знаю почему не работает на других формулах.
В файл добавил формулы в те же ячейки как и в рабочем файле. Диапазоны выделены, но выделять буду по одному диапазону.
 
Думаю достигнут предел длины текстового изменения. На первой формуле подстановка в 321 символ.
Я выше чуть подправил. особенно обработка ошибки мешалась.
По вопросам из тем форума, личку не читаю.
 
Цитата
БМВ написал:
достигнут предел длины текстового изменения. На первой формуле подстановка в 321 символ
Перед созданием темы я вручную опробовал и не видел проблем.
Например, в ячейке S6 793 символа.
Код
=ЕСЛИ($N$21>=95;ЕСЛИОШИБКА(ГПР(O6;{90;100;110;121:"Ach 90-99%";"Ach 100 -109%";"Ach 110 % -120%";"Ach 121 % & Above":0;0;0;0:0;0;0;0:0;0;0;0:2000000;4200000;5200000;5500000:#ДЕЛ/0!;#ДЕЛ/0!;#ДЕЛ/0!;#ДЕЛ/0!:0;0;0;0:0;0;0;0:0;0;0;0:0;0;0;0:3500000;5600000;6800000;7000000:#ДЕЛ/0!;#ДЕЛ/0!;#ДЕЛ/0!;#ДЕЛ/0!:0;0;0;0:0;0;0;0:2000000;2800000;3000000;3200000:#ДЕЛ/0!;#ДЕЛ/0!;#ДЕЛ/0!;#ДЕЛ/0!:0;0;0;0:0;0;0;0:0;0;0;0:1500000;2000000;3000000;3200000:#ДЕЛ/0!;#ДЕЛ/0!;#ДЕЛ/0!;#ДЕЛ/0!:0;0;0;0:0;0;0;0:1000000;1250000;1500000;1800000:#ДЕЛ/0!;#ДЕЛ/0!;#ДЕЛ/0!;#ДЕЛ/0!:0;0;0;0:0;0;0;0:0;0;0;0:1800000;2500000;3250000;3550000:#ДЕЛ/0!;#ДЕЛ/0!;#ДЕЛ/0!;#ДЕЛ/0!:0;0;0;0:0;0;0;0:0;0;0;0:0;0;0;0:2000000;3500000;4250000;5000000:0;0;0;0:0;0;0;0:2000000;3200000;4050000;4350000:15800000;25050000;31050000;33600000};30););)
 
все, накрылась идея.
если диапазоны в разных частях перекрываются или слипаются, то получим результирующий объединенный диапазон. что будет не корректным.
а примере
=IF($N$21>=95;IFERROR(HLOOKUP(N6;$E$117:$H$133;MATCH($C6;$D$117:$D$133;));)*L6;0)  получаем
$D$117:$H$133 - что естесвенно не корректно

Концепт 2 но по прежнему большой массив не вставит.
Скрытый текст
Изменено: БМВ - 20.03.2024 07:39:27
По вопросам из тем форума, личку не читаю.
 
Цитата
БМВ написал:
Концепт 2 но по прежнему большой массив не вставит
Не заводится макрос


А может упростить.. Жестко прописать ссылку на диапазон.
В выделенном диапазоне в формулах именно $T$90:$W$129 изменить в массив
Изменено: Михаил Л - 20.03.2024 06:52:50
 
Цитата
Михаил Л написал:
Не заводится макрос
да, там определением переменных намудрил, Это не проблема.
А вот
Цитата
Михаил Л написал:
Жестко прописать ссылку на диапазон.
не помогает ибо как оказалось найти это не так сложно, хоть и не в две строки, а заменить через замену не получается. Только если в каждой ячейке править, что дольше.

исправил выше
По вопросам из тем форума, личку не читаю.
 
Цитата
БМВ: заменить через замену не получается
приветствую!
Я не в теме задачи, но ведь всегда можно взять массив arr = Range().Formula, поработать с формулами, как со строками и выгрузить обратно Range().Formula = arr

Михаил Л, здравствуйте
Скажите, пожалуйста, если не секрет, в чём глобальный смысл данных действий? Зачем может быть нужно заменять ссылки на их значения?
Кстати, ссылка по теме замены ссылок на значения (есть ещё версия в надстройке Multex)).
Изменено: Jack Famous - 20.03.2024 09:41:08
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
замены ссылок на значения
или на массив?

Цитата
Jack Famous написал:
о ведь всегда можно взять массив arr = Range().Formula
это не изменит принципиально ничего, также перебор всех формул, и сделает только сложнее проверку на то, действительно ли взят диапазон, а не похожий текст. Также придется дробить на поддиапазоны в случае есливыделено несколько диапазонов. В чем смысл замены  - это во всех формулах чехом заменить диапазон , если он повторяется.
По вопросам из тем форума, личку не читаю.
 
Цитата
БМВ: или на массив?
разница только в {…}. Вообще ни о чём.
Цитата
БМВ: сделает только сложнее проверку на то, действительно ли взят диапазон, а не похожий текст.
вообще тебя не понял. Формулы начинаются со знака "=" — вот тебе и вся проверка.
Цитата
БМВ: Также придется дробить на поддиапазоны в случае есливыделено несколько диапазонов.
это называется области: Range.Areas. И тут тоже ничего сложного. Сложность в том, как написать парсер для строки формулы, а не как его применить для Selection.Areas.Count.
Цитата
БМВ: В чем смысл замены  - это во всех формулах чехом заменить диапазон , если он повторяется.
хоспади, ну не нужно ли ТЕБЕ объяснять, что "чехом" — это такой же цикл, только скрытый от твоих глаз. Встраиваешь в парсер статичный словарь и сохраняешь отобранные замены.
Изменено: Jack Famous - 20.03.2024 11:11:43
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Михаил Л написал:
В файл добавил формулы в те же ячейки как и в рабочем файле
Цитата
Jack Famous написал:
в чём глобальный смысл данных действий? Зачем может быть нужно заменять ссылки на их значения?
Все просто, зашить массив в формулу, а диапазоны данных удалить с листа.
Вообще там целая история с этими премиями. Первый раз сделал в PQ и PP, но мою работу проверяет финдиректор. Он вызвал меня и мне пришлось объяснять что такое срезы и почему при нажатии кнопки среза меняются данные, почему в файле только один лист, где все данные, как работает впр, не шарлатан ли я.
В итоге сказали сделать как у нормальных людей и мне пришлось для каждого сотрудника(40+ листов) делать отдельный лист и копипастить данные.  
Цитата
Михаил Л написал:
В файл добавил формулы в те же ячейки как и в рабочем файле
Формулы будут только эти, достаточно в макросе жестко прописать ссылку на диапазон.
Может сделать макрос для одной ссылки($T$90:$W$129 изменить в массив)? А я бы уже накопировал бы макросов под каждую ссылку.
 
Цитата
Jack Famous написал:
разница только в {…}. Вообще ни о чём.
ой ли.
Цитата
Jack Famous написал:
Формулы начинаются со знака "=" — вот тебе и вся проверка.
втексте будет "A1"=B1 -где диапазон , а где нет?
Цитата
Jack Famous написал:
И тут тоже ничего сложного.
ничего , но уже цикл по ним и отдельная обработка каждого что приведет клибо к невозможности найденный диапазон заменить сразу везде.
Цитата
Jack Famous написал:
что "чехом" — это такой же цикл, только скрытый от твоих глаз
да да, ты попробуй тоже продлеать с Массивной формулой.

короче, прежде чем свое непонимание высказывать, ты б разобраться попытался, в мелочах.
Цитата
Михаил Л написал:
Может сделать макрос для одной ссылки($T$90:$W$129 изменить в массив)?
это сильно упрощает задачу, но вы должны понимать, что подобное изменение ведет к росту объема файла, и тяжко для контроля.
строку подстановки из заранее определенного диапазона сформировать не сложно

это вот эта часть
Код
                                D = oArea
                                ReDim d1(1 To UBound(D, 2)), d2(1 To UBound(D, 1))
                                For i = 1 To UBound(D, 1)
                                    For j = 1 To UBound(D, 2)
                                        d1(j) = IIf(IsEmpty(D(i, j)), 0, D(i, j))
                                        If Not IsError(d1(j)) Then
                                            If Not IsNumeric(d1(j)) Then d1(j) = """" & d1(j) & """"
                                        End If
                                    Next
                                    d2(i) = Join(d1, ",")
                                Next
                                S = "{" & Join(d2, ";") & "}"


А пробежаться и заменить шило на мыло по всем ячейкам в выделенной области с формулами и заменить -ваще просто.

Цитата
Михаил Л написал:
Первый раз сделал в PQ и PP, но мою работу проверяет финдиректор. Он вызвал меня и мне пришлось объяснять что такое срезы и почему при нажатии кнопки среза меняются данные, почему в файле только один лист, где все данные, как работает впр, не шарлатан ли я.
- интересно, он в магазин наверно до сих пор с наличкой ходит.
Изменено: БМВ - 20.03.2024 13:01:24
По вопросам из тем форума, личку не читаю.
 
Цитата
БМВ написал:
подобное изменение ведет к росту объема файла
Увеличение на объем текста макроса? У  меня макросы в отдельной книге.
Или увеличение на объем массива в каждой формуле? Пусть увеличивается, там 110 формул, не будет критично.
Цитата
БМВ написал:
это сильно упрощает задачу
Может макрос покажете? Я сам не сделаю
 
да
Цитата
Михаил Л написал:
увеличение на объем массива в каждой формуле

Цитата
Михаил Л написал:
Может макрос покажете?
чтоб его показать, его надо написать ;-) . Может вечером, но не обещаю.

Однако вопрос
в приложении файл, который получен после работы макроса, который ниже.
Скрытый текст


То что можно переделать - можно. только нужно понимать оно того стоит или текущего достаточно, и если стоит , то более точно сформулировать что нужно.
По вопросам из тем форума, личку не читаю.
 
Цитата
БМВ написал:
или текущего достаточно
Этом макрос уже рабочий! В файле в выделенном диапазоне P6:S20 он отработает до первой ошибки. Однако если в диапазоне  T90:W129 убрать формулы, вызывающие ошибку(деление на ноль), то макрос отработает как надо.
Большое спасибо! Все отлично!
 
Цитата
Михаил Л написал:
Однако если в диапазоне  T90:W129 убрать формулы, вызывающие ошибку(деление на ноль),
а вот тут интересно. Что делать в таком случае. По идее обрабоать можно и заготовка есть
Код
                                        If Not IsError(d1(j)) Then
                                            If Not IsNumeric(d1(j)) Then d1(j) = """" & d1(j) & """"
                                        End If

нужно только решить и при наличии ошибки что-то поместить в массив.
По вопросам из тем форума, личку не читаю.
 
Цитата
БМВ написал:
нужно только решить и при наличии ошибки что-то поместить в массив
Например, три плюса "+++". Так будет видно в массиве что присутствуют ошибки.
Я вижу что нужно добавить else, но не знаю какое и куда
 
За следующим if
Код
Else
d1(j) = "+++"
По вопросам из тем форума, личку не читаю.
 
БМВ, Большое спасибо!
Так сработало
Код
                                        If Not IsError(d1(j)) Then
                                            If Not IsNumeric(d1(j)) Then d1(j) = """" & d1(j) & """"
                                           Else: d1(j) = """+++"""
                                        End If
 
На дробных числах потребовалось добавить замену запятой на точку
Код
For j = 1 To UBound(D, 2)
                                        d1(j) = IIf(IsEmpty(D(i, j)), 0, D(i, j))
                                         If Not IsError(d1(j)) Then
                                            If Not IsNumeric(d1(j)) Then
                                            d1(j) = """" & d1(j) & """"
                                            Else: d1(j) = Replace(d1(j), ",", ".")
                                            End If
                                         Else: d1(j) = """+++"""
                                        
                                        End If
                                    Next
Страницы: 1
Наверх