Сьогодні ми будемо вивчати написання макросів для Microsoft Excel і спробуємо застосувати їх на конкретному прикладі.
Почнемо з матчастини. Нам знадобиться: Microsoft Excel, одна голова і пара рук. Ексель "з коробки" володіє вбудованим компілятором VBA, тому встановлювати його додатково не потрібно.
Отже, почнемо з простого: створимо першу призначену для користувача функцію. Щоб увійти в редактор коду, натисніть Alt + F11. Ви побачите середу розробки Visual Basic, а зліва - менеджер проектів. У ньому натисніть на корені дерева правою кнопкою натисніть Insert -> Module. Тепер ми бачимо вікно для редагування коду. Створимо в ньому функцію, яка повертає універсальну газову постійну:
Function RUG () As Double RUG = 8.314472 End Function
Тепер ми можемо вставити цю функцію в будь-яке місце книги.
Тепер спробуємо створити функцію з параметрами.
Function sum (a, b) As Double sum = a + b End Function
Як бачите, використання функцій в VBA схоже на використання функцій в інших мовах. А тепер закінчимо наш Hello World і перейдемо до розгляду реального прикладу. Як приклад вирішимо диференціальне рівняння методом Рунге-Кутта 4 порядку.
Вихідні дані:
Для вирішення нам необхідно оголосити 5 функцій.
Перша функція буде безпосередньо обчислювати значення похідної за формулою, яка дана за умовою задачі. Функція виглядає так:
Function func (a As Double, f_k As Double, x As Double, t As Double) As Double func = 1 + a * x * Sin (t) - f_k * x * x End Function
Тут а і f_k - параметри рівняння, x - координата, t - крок за часом.
Метод Рунге-Кутта передбачає розрахунок чотирьох коефіцієнтів: k1, k2, k3, k4. Зверніть увагу: ми не можемо оголошувати функцію k1 безпосередньо - виникне конфлікт з номером комірки таблиці. Тому скористаємося префіксом.
Function f_k1 (h As Double, a As Double, f_k As Double, x As Double, t As Double) As Double f_k1 = h * func (a, f_k, x, t) End Function Function f_k2 (h As Double, a As Double, f_k As Double, x As Double, t As Double) As Double f_k2 = h * func (a, f_k, x + 0.5 * h, y + 0.5 * f_k1 (h, a, f_k, x, t)) End Function Function f_k3 (h As Double, a As Double, f_k As Double, x As Double, t As Double) As Double f_k3 = h * func (a, f_k, x + 0.5 * h, t + 0.5 * f_k2 (h, a, f_k, x, t)) End Function Function f_k4 (h As Double, a As Double, f_k As Double, x As Double, t As Double) As Double f_k4 = h * func (a, f_k, x + h, f_k3 (h, a, f_k, x, t)) End Function
Тут h - крок сітки. Інші параметри мають те ж призначення, що і в першій функції. Обчислення проводяться чисто по схемі Рунге-Кутта.
Тепер нам залишилося лише застосувати наші функції і вирішити диференціальне рівняння. Для цього нам знадобиться початкова умова. Його ми можемо вибрати будь-який, в даному випадку x (0) = 0.
Кому лінь розбиратися, розшифровую формулу:
Тепер розтягуємо нашу формулу на весь інтервал і отримуємо чисельне рішення.
Для наочності побудуємо графік:
Тут синьою лінією показаний графік знайденої функції, коричневої - її апроксимація методом найменших квадратів. Цей метод я описувати не буду, просто скажу, що в підсумку ми отримали рівняння x = -0.65t2 + 1.2664t-0.01992. Якщо вам цікава реалізація цього методу, можете подивитися його у вкладеному файлі.
Darth_Vaider ,
vr-online.ru