Страницы: 1
RSS
Как в формуле сделать все ссылки на диапазоны абсолютными (VBA)
 
Есть формула в ячейке. Как все ссылки в ней сделать абсолютными с помощью VBA.  
Помню была такая функция, но какая именно?
 
Не получается. Хотя похоже на то, что я видел.  
Ввожу формулу (Лист3!A1+Лист2!B5)*сумм(C7:C28) в ячейку A1  
В Immediate набираю: Range("A1").Formula = Application.ConvertFormula(Formula:=Range("A1"),FromReferenceStyle:=xlA1,ToReferenceStyle:=xlA1, ToAbsolute:=xlAbsolute)  
И в ячейке получаю просто результат
 
Помнится это был первый вопрос (или один из первых), который я задал на этом форуме. Если бы мне тогда ответили через 10 мин., то я, возможно, сказал бы спасибо и не задержался здесь :).  
К сожалению не смог найти этой темы.  
Есть готовый макрос, который конвертит туда-обратно, учитывая формулы массива  
http://www.ozgrid.com/VBA/formula-ref-change.htm
Bite my shiny metal ass!      
 
1) ConvertFormula работает с текстовой строкой  
 
2) свойство объекта Range по-умолчанию - Value, а не Formula  
 
Вывод: в первом параметре надо эксплицитно указывать свойство Formula  
 
Range("A1").Formula = Application.ConvertFormula(Formula:=Range("A1").Formula,FromReferenceStyle:=xlA1,ToReferenceStyle:=xlA1, ToAbsolute:=xlAbsolute)
KL
 
В продолжении темы хочу спросить, есть ли аналог функции ДВССЫЛ() в VBA.
 
Да!  
 
Range() ~ ДВССЫЛ()  
Application.Evaluate() ~ ДВССЫЛ()  
Range(...).Area(...).Cell(...) ~ ИНДЕКС()  
Range(...).(...) ~ ИНДЕКС()  
Range(...).Offset(...).Resize(...) ~ СМЕЩ()  
 
А еще можно так:  
 
Range("INDIRECT(""A1"")") - бесполезно, но интересно  
Range("INDEX((A1:A60,C1:D10),0,2,2)")    
Range("OFFSET(A1,2,5,3,10)")    
 
То же самое с Application.Evaluate(), только с Evaluate можно еще получать любые значения (вкл. значения ошибки) и массивы этих значений, а не только объект Range  
 
Ну и конечно [...] требующее "хард-кодинга"
 
 
:-)
KL
 
Что-то с точками намудрил :-)  
Вторая попытка:  
 
 
Range() ~ ДВССЫЛ()  
Application.Evaluate() ~ ДВССЫЛ()  
Range().Area().Cell() ~ ИНДЕКС()  
Range()() ~ ИНДЕКС()  
Range().Offset().Resize() ~ СМЕЩ()  
 
А еще можно так:  
 
Range("INDIRECT(""A1"")") - бесполезно, но интересно  
Range("INDEX((A1:A60,C1:D10),0,2,2)")    
Range("OFFSET(A1,2,5,3,10)")    
 
То же самое с Application.Evaluate(), только с Evaluate можно еще получать любые значения (вкл. значения ошибки) и массивы этих значений, а не только объект Range  
 
Ну и конечно    
[A1]
[INDIRECT("A1")]
[DefinedName]
 
требующее "хард-кодинга"  
 
 
:-)
KL
 
Не перестаю восхищаться широте возможностей синтаксиса VBA.  
 
Спасибо Кирилл, но чтобы пользоваться надо понимать, поэтому еще вопрос:  
 
Какую смысловую нагрузку и действие осуществляет символ "~" и что есть "хард-кодинг". Потому как [...] использую только для именованных диапазонов.
 
Владимир.  
 
P.S. есть ли у Вас простенький пример с использованием этих конструкций,  
дюже мудреный синтаксис...
 
{quote}{login= VovaK}{date=23.09.2009 08:34}{thema=}{post}Не перестаю восхищаться широте возможностей синтаксиса VBA.  
 
Спасибо Кирилл, но чтобы пользоваться надо понимать, поэтому еще вопрос:  
 
Какую смысловую нагрузку и действие осуществляет символ "~" и что есть "хард-кодинг". Потому как [...] использую только для именованных диапазонов.
 
Владимир.  
 
P.S. есть ли у Вас простенький пример с использованием этих конструкций,  
дюже мудреный синтаксис...{/post}{/quote}  
 
1) под ~ я подразумевал "приблизительно равно"  
2) "хард-кодинг" - жесткое кодирование, т.е. содержимое [] не может задаваться переменными.
3) на самом деле, думаю я вас слегка запутал тильдами(~), синтаксис самый что ни наесть обычный :-)    
 
********************************************  
Для функции ДВССЫЛ()  
 
а. точно также превращает текстовую ссылку в диапазон  
Range("A1:A10")    
 
б. аналогично  
Application.Evaluate("A1:A10")    
 
********************************************  
Для функции ИНДЕКС()  
 
а. данная конструкция точно воспроизводит эффект всех 4-х аргументов ИНДЕКС(). Range задает 1-й арг, Cells - 2-й и 3-й, а Area - 4-й  
Range("A1:A10,B2:B5,D7:D12").Area(2).Cells(3,1)  
 
б. почти аналогично, но не учитывает области  
Range("A1:A10")(3,1)    
 
********************************************  
Для функции СМЕЩ()  
 
а. данная конструкция точно воспроизводит эффект всех 5-и аргументов СМЕЩ().Range задает 1-й арг, Offset - 2-й и 3-й, а Resize - 4-й и 5-й  
Range("A1:A10").Offset(1,2).Resize(5,5)  
 
********************************************  
Это лишь примеры того, что Range позволяет использовать в качестве аргумента формулы рабочего листа возвращающие ссылку. Данные формулы должны быть на английском со всеми вытекающими. Формулы могут быть достаточно сложными, главное, чтобы они возвращали объект Range. Честно говоря, на практике сам еще никак не применял, но интересно :-)  
 
а. Range("INDIRECT(""A1"")")  
б. Range("INDEX((A1:A60,C1:D10),0,2,2)")    
в. Range("OFFSET(A1,2,5,3,10)")    
 
********************************************  
Application.Evaluate() и [] по сути - одно и то же, но первая работает с текстовой строкой в качестве аргумента и, значит, принимает переменные, а вторая требует жесткого прописывания формулы и не работает с переменными. Писать в [] в некотором смысле - что писать в ячейку листа.
 
а. Примеров с Application.Evaluate() на форуме масса, т.ч. я не буду ее особо расписывать.  
 
б. про [] почти все знают, что можно ее использовать вместо Range("A1"), но у нее возможностей побольше
[A1]
[A1:A5,C2:D5]
[MyDefinedName]
[2*2]
[A1+B1+VLOOKUP("JAN",Sheet3!A1:B11,2,0)]
KL
 
Кстати можно прописывать лист для диапазона возвращаемого [A1] по-разному
 
Sheet1.[A1]
[Sheet1!A1]
KL
 
Спасибо Кирилл,  
 
Очень доходчиво. Буду пробовать []. Ранее использовал для именованных областей, очень удобно.
 
Владимир.
Страницы: 1
Читают тему
Наверх