C, PHP, VB, .NET

Дневникът на Филип Петров


* Записване на макроси – пример с Excel

Публикувано на 27 септември 2015 в раздел Макроси VBA.

Както вече споменахме, почти всяко наше действие в софтуерния продукт би могло да бъде програмирано във VBA. Това включва писане на текст, натискане на бутон от лентата с интструментите, форматиране, и др. Записването на макроси е начин да генерираме автоматично код във VBA, вместо да го пишем на ръка. С натискането на специален бутон ние караме VBA да започне да следи какво правим в софтуерния продукт. След като извършим желаната последователност от действия и натиснем бутон стоп, ние можем да ги запазим и впоследствие да преизползваме.

Нека например имаме документ в Excel, в който ще запазим множество таблици с имена, факултетни номера и оценки на студенти – всяка таблица ще отговаря на различна учебна група. В допълнителна клетка ще изчисляваме техния среден успех. Искаме да направим макрос, чрез който при добавяне на нова таблица да можем да извършим автоматично стандартното форматиране – добавянето на заглавния ред и формулата за среден успех. Ще започнем от празна таблица с нашата първа учебна група. Първото, което трябва да направим, е да стартираме записването на макроса. Отидете на Developer и изберете „Record macro“. Опцията „Use Relative References“ (намира се точно под бутона Record macro) в този случай няма да бъде маркирана. Чрез нея се указва дали нашите действия да бъдат с релативни или с абсолютни позиции. Ако са с абсолютни, макроса ще записва точните клетки където извършваме действието и ако после го приложим, той ще извърши действията точно в тези клетки. Ако действията са релативни, при прилагането на макроса действията ще се извършат относително спрямо мястото на клетката, която текущо сме маркирали. Понеже ние ще правим заглавен ред, който е винаги най-горе на таблицата, ще запишем макрос с абсолютно позициониране.

record-macro

Ще излезе диалогов прозорец, в който трябва да зададете име на макроса, бърза клавишна комбинация за неговото стартиране (ако желаете да има такава), местоположение за запазване на кода (ще го запазим в This Workbook, т.е. текущия документ) и описание по желание (то ще бъде добавено като коментар във VBA кода).

record-macro-dialog

Сега започваме да пишем нашия заглавен ред. Добавяме текст за колоните, формулата за средния успех и накрая оразмеряваме колоните, както е показано на картинката по-долу:

recorded-macro

След като извършите всичко, натиснете „Stop recording“ от Developer менюто. Вашият макрос вече е записан. Нека видим какъв код е генериран. Отворете VBA редактора (ALT+F11). Ще видите, че под обектите се е появил раздел „Modules“. В него има един модул с име „Module1“. Отворете го и ще видите генерирания код:

macro-code

Самият код е доста описателен. Range(„A1“).Select казва „маркирай клетка A1“. ActiveCell.FormulaR1C1 = „Име“ означава, че в активната клетка (това е маркираната клетка, т.е. A1), формулата трябва да стане текста „Име“. Нататък нещата се повтарят за следващите клетки.

По-особеното идва при формулата за средния успех. В Excel я написахме като „=AVERAGE(C:C)“, а тук е записана като „=AVERAGE(C[-1])“. Това е конкретна особеност на Excel и е свързана с т.нар. R1C1 нотация. Стандартно ние се обръщаме към клетките първо с името колоната, а след това с реда – например клетка C2 ще е клетката на колона с име C и ред с номер 2. При R1C1 нотацията ние първо се обръщаме към номера реда, а след това към номера на клетката – т.е. при тази нотация вместо клетка C2 вече ще пишем R2C3, защото е 2-ри ред и 3-та колона. В случая R е префикс за Row (ред), а C за Column (колона). Ако поставим ъглови скоби и число, ще имаме релативна позиция – числото в ъгловите скоби указва с колко напред/назад (при редове) или нагоре/надолу (при колони) да бъде преместена текущата позиция. Нека например се намираме в клетка E1 (Range(„E1“).Select). Искаме в нея да има формулата C2*10. Ето вариантите за реализиране на това във VBA:

  • A1 нотация:
    • ActiveCell.Formula = „=$C$2 * 10“ – добре познатото ви изписване с абсолютна позиция
    • ActiveCell.Formula = „=C2 * 10“ – добре познатото ви изписване с релативна позиция
  • R1C1 нотация:
    • ActiveCell.FormulaR1C1 = „=R2C3 * 10“ – ще направи позицията абсолютна, т.е. реално ще имаме A1 формула „=$C$2 * 10“
    • ActiveCell.FormulaR1C1 = „=R[1]C[-2] * 10“ – от клетка E1 слиза един ред надолу (R[1]) и се връща два реда назад (C[-2]). Резултатът е с релативна позиция, т.е. в A1 нотация ще е „=C2 * 10“

При R1C1 нотацията ако пропуснем R или C, това ще означава „всички редове“ или „всички колони“. Е, от примера с нашия макрос, VBA е записал A1 формулата ни „=AVERAGE(C:C)“ с R1C1 нотация като =“AVERAGE(C[-1])“, защото в момента се намираме в клетка D2 и в случая C[-1] означава „всички редове“ (R е пропуснато) и „една колона назад“ (C[-1]). VBA винаги записва макросите с R1C1 нотация. Вие разбира се може да използвате тази, която ви е по-удобна.

Нека сега изпълним създадения макрос. Добавете нова таблица и от Developer менюто изберете „Macros“. Маркирайте вашия макрос и натиснете Run:

run-macro

В новият Sheet2 автоматично ще се извърша действията от записания код.

Накрая, за да направим автоматизацията пълна, бихме искали да извикваме този макрос автоматично при добавяне на нова таблица в документа. Това се постига чрез създаване на събътие (Event). В случая събитието ще е за целия документ, т.е. трябва да бъде добавено в ThisWorkbook. Кодът, който ни трябва, е следния:

Private Sub Workbook_NewSheet(ByVal Sh As Object)
   With Sh
      Call MyHeaderMacro
   End With
End Sub

new-sheet-event

Workbook_NewSheet е запазено име за подпрограма – в случая това е подпрограма, която се изпълнява автоматично при добавяне на нова таблица (new sheet). В Excel има голямо множество от такива събития за всеки различен обект. Можете да ги видите като натиснете стрелката на дясното падащо меню над кода:

events-list

Ключовата дума „Private“ засега няма да я разискваме. Подадения входен параметър (ByVal Sh As Object) e новата таблица – към нея ще се обръщаме чрез името на променливата „Sh“. С блоковия оператор „With“ казваме, че в момента работим с таблица Sh, а с „Call MyHeaderMacro“ извикваме вече записания от нас макрос. Вече сме готови – автоматизирахме процеса на добавяне на заглавен ред в нови таблици на нашия документ!

 



Добави коментар

Адресът на електронната поща няма да се публикува


*