Как программировать в экселе. Линейное программирование в Excel

В дополнение к советам, как научиться писать макросы VBA для Excel , расскажу и свою историю - как я учился программированию на VBA.

Началось всё в прошлом веке, в 1993 году, когда я учился в школе. На уроках информатики, у нас в классе, стояли компьютеры-монстры под названием «Корвет» , и мы писали на них простенькие программы на Бейсике. Компьютеры эти отличались от «нормальных» (IBM-совместимых) весьма заметно - у них был монохромный дисплей, напрочь отсутствовал жесткий диск и дисководы для дискет, и единственное, что на нём запускалось (автоматически, после загрузки) - это интерпретатор языка Basic.

Вообще-то, интерес к программированию у меня проявился раньше - в возрасте 9 лет, когда я увидел в журнале «Моделист-конструктор» за 1988 год (который читал регулярно, от корки до корки) какие-то машинные коды для компьютера «Специалист» . Меня тогда очень заинтересовала возможность вбить в компьютер какие-то буквы и цифры, чтобы заставить его делать то, что мне хочется. Увы, финансовое положение моих родителей в те времена оставляло желать лучшего, и о покупке какого-либо подобия компьютера не могло быть и речи. Так что я развлекался тем, что переписывал эти коды из журнала в тетрадку, в надежде, что когда-нибудь у меня появится компьютер, и я смогу им управлять:)

Поскольку в те времена домашний компьютер был роскошью (лишь у некоторых были дома «Спектрумы» , а кому-то повезло обзавестись дорогущим IBM PC 286), осваивал Basic я исключительно в школе, порой задерживаясь после уроков. Школьной программой было предусмотрено всего 2 года обучения предмету «Информатика» (10 и 11 классы), но я с детства интересовался всякой электроникой, поэтому стал посещать занятия с 8 класса, читая там единственную книжку-инструкцию по «Корвету» (вот эта книга , с которой начался мой путь в программирование, она же в ПДФ), и пытаясь составлять простенькие программы. Вскоре преподаватель стала пускать меня за главный компьютер (только на нём была возможность сохранять программы на дискету 5.25" - и то, для этого приходилось немало потрудиться) - и мои программы стали намного сложнее. Однажды даже удалось реализовать игру «Покер» с графическим интерфейсом (получилось около 2000 строк кода) - это при том, что интерпретатор Basic позволял выводить на экран только символы, и графические примитивы.
В итоге, к окончанию школы (1996 год) я умело пользовался циклами, и имел некоторый опыт составления алгоритмов.

Что касается алгоритмов - этот термин до сих пор вызывает у меня аллергию. Во времена учебы в школе, на лекциях по информатике (учился я достаточно неплохо, и нас, победителей всяческих олимпиад, отправляли на дополнительное обучение высшей математике и информатике в очно-заочную школу при УрГУ), нас заставляли писать алгоритмы на каком-то псевдокоде (смеси русского языка с Turbo Pascal). Поскольку в программировании я заметно отставал от сверстников (они учились на IBM-совместимых компьютерах, где был этот самый Паскаль и многое другое, а я, кроме Бейсика, ничего не знал и не видел), было очень сложно освоить синтаксис алгоритмического языка. Кроме того, я не понимал (и сейчас не понимаю), зачем нужно тратить час на составление алгоритма для простейшей программы, если можно просто открыть редактор, и написать несколько строк кода (для меня, нормально знающего английский язык, синтаксис языка BASIC был куда понятнее, чем этот загадочный алгоритмический псевдокод). Про блок-схемы вообще речи не идёт - как вспомню институт, где нас заставляли рисовать блок-схемы (на несколько листов формата A4) для простейших программ из 10 строк, перестаю понимать, как вообще может не пропасть желание изучать программирование после всего этого...

После окончания школы, в институте, я немного изучал Turbo Pascal, на чём моё обучение программированию остановилось на десятилетие (компьютера дома и на работе не было), и я забыл почти всё, что изучал на уроках информатики.
Однако в 2004 году, у меня на работе, начальство наконец-то решило заменить печатную машнку (на которой я уже очень умело колотил по клавишам) на простенький компьютер (это был Pentium-1 с 64 мегабайтами ОЗУ и Windows 98). Учитывая, что Windows я увидел тогда впервые, мне пришлось обучаться работе на компьютере «с нуля».

Освоил компьютер я быстро, т.к. уже на второй день Windows слетела после безуспешной попытки разгона процессора, и мне пришлось в экстренном порядке осваивать переустановку ОС и программ. Человек, помогавший мне в первый день знакомства с компьютером устанавливать операционную систему и основные программы, не имел возможности помогать мне постоянно. Он оставил мне дистрибутивы Windows и Office, пару дисков в разными утилитами, после чего объяснил мне, как вбивать и форматировать текст в Word, как открывать и сохранять файлы через меню программ, и ушел, пожелав мне удачи. Мне ничего не оставалось, как осваивать систему «методом тыка».

Каким счастьем (после печатной машинки) была возможность сохранять и редактировать напечатанные документы... и меня нисколько не смущало, что запуск Word занимал около 20-30 секунд (а CorelDRAW грузился пару минут). Компьютер стал моим главным увлечением - за пару месяцев я освоил основные программы, через полгода вовсю ковырялся в реестре, восстанавливая слетевшую винду (кто помнит Win98 - тот меня поймёт), попутно освоил архитектуру компьютера (постоянно приходилось перетыкать модули памяти, подключать дополнительные жесткие диски, и т.п.)

Работа моя заключалась в подготовке различных документов (актов, приказов и т.п.), и я стал задумываться, как же её упростить (не люблю делать одно и то же изо дня в день). Почти сразу я обратил внимание на пункт «Редактор Visual Basic» в меню Microsoft Word, и полез смотреть, что это за зверь такой. Потыкался, поглядел встроенную справку, - но мало что понял. Ничуть не похож был этот Basic на тот, что я изучал в школе. Разобрался, что можно рисовать формы с кнопочками и текстовыми полями, - но как заставить это работать, пока не понимал. Доступа в интернет не было, так что поглядеть примеры использования я не мог.

Так бы и забросил я это дело, но тут, в один прекрасный день, файлы Word стали открываться медленно, и при их открытии стала выскакивать какая-то ошибка. Стал разбираться - и обнаружил, что ошибка возникает при выполнении макроса из 20 строк, загадочным образом оказавшегося во всех моих документах. Поглядев код, я понял, что передо мной ничто иное, как макровирус, заражающий все открываемые файлы Word, и безуспешно пытающийся отправить какие-то данные по сети. (кстати, это был первый и последний раз, когда я видел макровирус, - с тех пор через меня прошли тысячи файлов Excel и Word, и я ни разу не встречал в них макровирусы). Это меня заинтересовало - если макрос может собрать данные с компьютера, сам себя скопировать в другие файлы, да ещё что-то отправить на другой IP адрес, - значит, при помощи макросов можно сделать практически что угодно!

И я стал осваивать макросы - читал встроенную справку по VBA, пробовал примеры кода из этой справки, писал простенькие циклы (что я помнил ещё со школы), рисовал несложные формы, и т.п. Вовсю пользовался записью макросов в Word, оптимизируя полученный код. (c Excel я тогда не работал - вообще плохо понимал, для чего он может быть полезен). Пользы это приносило мало - но мне было интересно, т.к. я увлекался программированием ещё со школьной скамьи. Постепенно, моя работа стала упрощаться, хотя на автоматизацию уходило времени больше, чем потребовалось бы на ручное выполнение всех действий.

Однажды, в 2006 году, мне реально понадобились навыки программирования на VBA. По работе, понадобилось создавать (рисовать в CorelDRAW) много однотипных планов эвакуации (это такие чертежи помещений со стрелочками, и специфическими значками). Рисовать-то их можно было и вручную, но, чтобы результат соответствовал ГОСТу, было необходимо соблюдать разные пропорции и расстояния между элементами. Двигать значки по листу, подгоняя «на глаз» рассстояние от линий и соседних значков, быстро надоело. А ещё надо было всё выравнивать, быстро рисовать и красиво соединять пунктирные линии, каждый раз выполнять предпечатную подготовку, и т.д. и т.п... В итоге, потратив 2 или 3 месяца на автоматизацию этого процесса, я добился сокращения времени изготовления чертежа в несколько раз. К тому же, приятно было смотреть на лица коллег, когда на их глазах происходили чудеса, - линии рисовались и двигались на экране сами, стрелки выравнивались и загибались, всё мелькало, и через минуту я уже вытаскивал из компьютера дискету, готовую к отправке к типографию (с двумя копиями файла, полностью готового к печати)

На дворе было лето 2008 года. Заняться мне было нечем, и я решил помочь с решением задач в Excel людям, обращающимся за советом на форумы. Втянулся я в это быстро - приятно было слышать благодарности от людей, которым моя «волшебная кнопка» сэкономила много часов однотипной работы. К тому же, помощь требовала совсем немного сил, - порой достаточно было написать 2-3 строки кода. Тут я начал понимать, что знаю в VBA и Excel ещё очень и очень плохо, - и стал учиться, разбираясь в решениях, предлагаемых более опытными коллегами.

Потребовалось 2 или 3 года, в течении которых я помогал на форумах всем желающим, чтобы начать чувствовать себя в Excel уверенно. Поначалу писал совсем простенькие макросы, потом - более сложные. Спустя год ко мне начали обращаться с заказами - тогда я готов был работать за копейки (ибо целью было не зарабатывание денег, а помощь людям). Первым более-менее серьёзным заказом, за который я взял плату, была программа для сотрудников приемной комиссии - пришлось реализовывать базу данных в Excel. За 3 недели мучений и переделок (заказала программу студентка, которая сама точно не знала, что ей нужно) программа была написана - и заработал я на этом около 3500 рублей. С тех пор со студентами я не работаю - денег мало, техзадания нет, куча просьб о переделке (потому что преподу что-то не понравилось), да и вообще неприятно осознавать, что программа будет запущена всего 1 раз, а потом ей никто пользоваться не будет.

В 2009 году я сделал сайт сайт. Сайтом это можно было назвать лишь с натяжкой - он состоял из одной страницы (вот как он выглядел в то время). Пользы от такого сайта, как вы понимаете, быть не могло, - те, кто заходил на сайт, и без того уже знали, чем я занимаюсь. А хотелось большего - чтобы сайт приносил пользу, как мне, так и своим посетителям. Поэтому мне в экстренном порядке пришлось изучать сайтостроение, - и, благодаря помощи друга, через несколько месяцев сайт приобрел движок в виде CMS Drupal (самому мне было бы это не осилить). Что публиковать на сайте, я тогда ещё не придумал, потому начал использовать его в качестве записной книжки - публиковать там полезные универсальные макросы и функции, чтобы не приходилось их каждый раз искать в разных файлах, вспоминая, когда и кому я делал подобное.

Не прошло и полгода, как посещаемость сайта стала расти. Выяснилось, что выкладываемые мной макросы интересны многим, и это дало мне стимул к дальнейшему развитию ресурса - я стал выкладывать готовые решения в виде файлов Excel и надстроек, уделять больше внимания функционалу и структуре сайта. Вместе с тем, стало расти количество заказов, - посетители сайта видели, что возможности макросов безграничны, и обращались ко мне с просьбой автоматизировать свою работу. Но, всё равно, заказов было слишком мало, чтобы всерьёз рассматривать программирование как источник дохода, - в месяц было 2-3 небольших заказа. Даже если и заказывали относительно сложную программу, то радости это не приносило - я, по неопытности, сразу оговаривал сумму, а потом, по доброте душевной, соглашался на разные доработки, отсутствовавшие в изначальном задании на программу. В результате этого, я неделями работал над одной программой, а зарабатывал совсем немного - поскольку изначально предполагалось, что сделать надо совсем немного.

Но это время (почти год) не было потеряно впустую - денег я не заработал, но зато приобрел бесценный опыт в разработке пользовательских интерфейсов (приходилось рисовать формы ввода с сотнями полей), решении нестандартных для Excel задач (обработка сайтов, работа с файлами, изображениями, и т.д.), заодно научившись с полуслова понимать заказчиков и их задания (ээх, видели бы вы, как некоторые люди формулируют задания на сложные программы в одном предложении из 10 слов...). Телепатом я ещё не стал, но стал догадываться, чего на самом деле хочет заказчик, и предлагал людям именно то, что им нужно (большинство сами не знают, чего хотят, когда обращаются за помощью). И всё было бы хорошо, если не отсутствие заказов (к тому времени, помогать людям на форуме стало надоедать - каждый день одни и те же вопросы, никто не хочет пользоваться поиском, да ещё и студенты-халявщики одолевают).

И начал я думать, как же увеличить количество заказов, - хотелось, чтобы моё хобби наконец-то начало приносить ощутимый доход. Опять пришлось удариться в сайтостроение - освоить основы SEO, дизайна, да и сайтостроительства в целом. И однажды понял я, чего до сих пор нехватало на сайте, - большой кнопки для оформления заказа. Недолго думая, в течении 5 минут эта кнопка (которую сейчас вы можете созерцать в левом верхнем углу страницы) была добавлена на все страницы сайта. Результат не заставил себя долго ждать - в течение месяца я получил заказов больше, чем за весь предыдущий год.

Наступил 2012 год. Количество заказов выросло до такого объема, что одному мне осилить их не было никакой возможности. Часть заказов я стал передавать своим коллегам (особенно крупные и сложные заказы), ибо всех денег всё равно не заработать, да и сидеть сутками за монитором не очень хочется. Попутно на основной работе (с 8:00 до 17:00 я работал инженером в местном интернет-провайдере) заметно выросла нагрузка, и я перестал успевать писать макросы в рабочее время. В итоге, на развитие сайта времени совсем не оставалось - вечерами только успевал разгребать часть заказов, и в почте стали копиться непрочитанные письма.

Пора было что-то менять в своей жизни - делать выбор между работой и программированием. И вот, в середине июля 2012 года, я этот выбор сделал - на основной работе написал заявление на увольнение, решив посвятить себя программированию (разработке макросов для Excel). С тех пор, свободного времени у меня более чем предостаточно, потому я планирую вновь заняться расширением сайта, и более активно работать над заказами (чтобы исключить ситуации, когда заказчики по нескольку недель ждали свои макросы).
Что из всего этого выйдет - пока не знаю, время покажет. Думаю, спрос на макросы для Excel будет сохраняться ещё как минимум 2-3 года, так что без хлеба с маслом я не останусь.

Также в планах на ближайшее будущее - разработка и публикация условно-бесплатных надстроек для Excel (первые пробы пера на этом поприще дали неплохие результаты).
А дальше - планирую заняться разработкой баз данных (с веб-интерфейсом), и постепенно перейти на работу с веб-сервисами.

<спустя 4 года, решил продолжить статью>

И вот на дворе уже 2016 год. К моей радости, Microsoft пока не отказывается поддержки от VBA в Excel, потому, я продолжаю трудиться в этой сфере. Эти 4 года сильно изменили мою жизнь, — доходы выросли в несколько раз, я начал много путешествовать, на работу оставалось меньше времени. Количество заказов на макросы постоянно увеличивалось, потому я стал сотрудничать с несколькими программистами, которым передавал заказы, когда не справлялся сам из-за отсутствия времени. Кто-то из моих коллег (кому я отдавал заказы в работу) со временем пропадал, а другие, наоборот, все активнее сотрудничали со мной, — и теперь у меня есть команда, решающая любые задачи (один коллега берет простые макросы, и делает их быстро, другой делает сложные макросы с использованием нестандартных решений, третий занимается "мутными" объемными заказами, где надо пару недель обсуждать задание, и потом еще месяц это делать, четвёртый специализируется на формулах, пятый настраивает парсеры, и т.д., — у каждого своя сфера деятельности).

Подобрать хорошую команду было делом непростым, — хотя я сам никого особо не искал (половина сами ко мне обратились за работой, остальным я написал сам, потому что знал из всех по форумам Excel как хороших спецов), не со всеми удавалось работать продолжительное время. Одни редко появлялись в сети, и недостаточно быстро реагировали на заказы, другие воспринимали работу больше как хобби (если внезапно нет желания работать, такой человек мог на неделю, а то и месяц, пропасть, не предупредив ни меня, ни заказчика). Один кадр даже умудрился кинуть меня на деньги (взял несколько заказов, и пропал, не заплатив мне мою комиссию). Но всё это в прошлом, — сейчас со мной только проверенные ребята (с кем я работаю уже несколько лет), которые берут заказы любой сложности, и всегда доводят работу до конца.

Поскольку мне удалось разделаться с «текучкой» (большим количеством мелких заказов, хоть приносящих и неплохой доход, но занимающих 100% времени), я стал уделять больше внимания разработке и продвижению универсальных надстроек для Excel . Сейчас в моём арсенале 9 таких надстроек, но успешно продаются только 5: FillDocuments (самая первая моя работа, до недавнего времени была в лидерах по доходам, и пользуется стабильным спросом, поскольку там реализовано уже всё, что только может пригодиться пользователям для заполнения документов), PastePictures (продается с 2012 года, но популярность стала набирать сравнительно недавно), Unification (3 года назад это была самая сложная из моих программ), Lookup (самая простенькая из моих надстроек, по сути являющаяся заменой формулы ВПР, — но очень популярная среди пользователей) и Parser (универсальный парсер для сбора данных с сайтов и файлов, самая навороченная из моих программ на сегодняшний день, — 17.600 строк кода). Касательно парсера, — ещё в 2013 году мне казалась абсолютно нереальной затея сделать что-то подобное (и я отказывал заказчикам, говоря о невозможности сделать универсальное решение для сайтов по типу Unification - программы обработки прайсов), но потом количество заказов на парсеры сайтов стало увеличиваться, и я решил попробовать, о чём ни разу не пожалел, — доходы от решений на базе этой надстройки превзошли все мои ожидания.

Но не все программы пользовались успехом. От продаж одной программы (YandexMarket) я вообще отказался, — сайт слишком часто менялся, программа требовала доработок, алгоритм поиска нужных данных был неочевиден, потом появилась капча, — и я решил, что не стоит тратить время на дальнейшее развитие программы, вернув деньги нескольким покупателям. Другие программы, такие как BarcodeScanner, Labels, SearchText, хоть и окупили потраченное на разработку время, и продолжают приносить доход, — но не идут ни в какое сравнение с пятеркой программ-лидеров.

По мере развития вышеописанных универсальных надстроек, сформировался так называемый «движок» программы, — набор макросов и элементов интерфейса, позволяющий быстро сделать готовое к продаже решение из любой идеи. Движок поначалу нужен был для поддержки обновлений (чтобы пользователь мог в одно нажатие проверить и установить обновление), позже он обрел функционал защиты (хакеры стали обращать внимание на мои решения, поскольку спрос на них рос с каждым годом, — и пришлось мне изобретать различные схемы защиты от нелегального использования, при том, что встроенная защита кода в Excel никуда не годится, ибо снимается за пару секунд). Попутно пришлось делать функционал активации и обновления программ на стороне сайта, - начал немного разбираться в PHP и MySQL, делая скрипты, взаимодействующие с движком программы.

Последние пару лет, основное время у меня уходит на обеспечение техподдержки (покупателей программ с каждым годом все больше), и на развитие надстройки-парсера, как самого популярного и перспективного из моих решений (добавляю новый функционал, публикую примеры настроенных парсеров). Мой уровень программирования, благодаря парсеру и новому движку программ, заметно вырос, — хоть мой код и 5 лет назад был вполне качественным и работал без сбоев, но теперь я более ответственно подхожу к оформлению кода, столкнувшись с необходимостью многолетней поддержки своих надстроек с многими тысячами строк кода. Сейчас, попутно со внедрением нового (многоязычного) движка во все надстройки, я произвожу рефакторинг (обновление) кода, делая его более простым, понятным, и универсальным. Кстати, насчёт многоязычности, — я решил продавать свои надстройки за пределами СНГ, и даже сделал отдельный сайт (чтобы выложить там только универсальные надстройки, с интерфейсом и описанием на разных языках), но пока всё лень этим заниматься. Может, когда-нибудь до этого руки и дойдут (а пока и из СНГ покупателей хватает)

В планах на будущее (по состоянию на сентябрь 2016 года), — развить направление парсинга сайтов в Excel, и наконец-то сделать видеоинструкции к своим программам (мне не лень и пару недель подряд добавлять в программу новый функционал, в то время как пользователи и с имеющимся разобраться не могут, ввиду отсутствия полноценной справки. Ну не люблю я записывать видеоролики))
Ну и пора уже выходить на международный рынок, раз все мои программы стали многоязычными (хотя перевод есть только на английский пока, и то частично)

<продолжение следует>

Для упрощения сбора информации, автоматизации ввода и вывода данных и многого другого используется программирование в excel.

Видео по написанию (программированию) макросов на VBA в Excel

VBA (Visual Basic for Applications) — разновидность языка программирования Visual Basic, входящая в пакет Microsoft excel

Программирование в excel ускоряет выполнение разнообразных задач на компьютере.

При написании кодов в excel программист использует:

  • Для написания кода существует два основных способа: писать внутри листа; внутри книги. Любая программа в рабочей среде excel начинается с ключевого слова «SUB», далее идет любое название с использованием букв или цифр, после чего открываем и закрываем скобки () и нажимаем «ENTER», образуется рабочая среда для написания программы. В рабочей среде набираем Аpplication, указываем ThisWorkBooks — эта книга, далее Sheet — листы, далее Cells(5,1) — номер ячейки, сначала пишется строка потом колонка. Программирование будет иметь такой вид: Аpplication — ThisWorkBooks — Sheets — Сells(5,1). Присваиваем этому адресу значение 10 через ключевой оператор присваивания «=» и запускаем программу на исполнение нажатием на кнопку «RunSub» или клавишей «F5». Присвоенное значение 10 окажется в указанном месте.

При работе с данным объектом в excel используется «среда разработки». «Среда разработки» вызывается сочетанием клавиш Сtrl+F11, после чего необходимо выбрать вкладку «View», далее «Обозреватель проекта», на котором будет отображено три элемента, два листа рабочей книги и сама книга excel.

DOM — Document object model (объектная модель документа) — независимый программный интерфейс, дающий возможность скриптам и программам находить доступ к содержимому , XHTML и HTML документов и менять оформление и структуру данных документов. DOM не ограничивает структуру документа, а представляет его в виде дерева узлов, любой из которых является элементом, атрибутом, графическим или текстовым объектом.

  • «Работа с переменными» — это слова или буквы, которые содержат в себе какое-то значение, например: Х=5, Y=10, с ними можно производить любые математические операции. Допустим, чтобы найти сумму данных значений с помощью программирования, в рабочей среде вводим следующую программу: Cells(2,1) = X+Y нажимаем «RunSub» или «F5» во 2 строке, 1 столбца отобразится 15 — сумма программируемых значений. Помимо чисел в значениях могут содержаться слова, единственное отличие, что программируемые слова должны браться в кавычки.

Программирование удобно в освоении и может использоваться обычными пользователями. Разработка макрокоманд (макросов) в VBA автоматизирует рабочий процесс увеличивая его производительность.

Оптимизационные модели используются, чтобы найти ответы на вопросы типа:

  • как составить расписание для сотрудников колл-центра, чтобы оно соответствовало их отпускным запросам, сбалансировало переработки и исключало круглосуточные дежурства?
  • какие возможности бурения нефтяных скважин использовать для получения максимального дохода, держа при этом под контролем все риски?
  • когда следует делать новые заказы в Китае и как их доставлять, чтобы минимизировать стоимость и соответствовать ожидаемому спросу?

Скачать заметку в формате или , примеры в формате

Целью оптимизации всегда является «максимизация» или «минимизация». Самая распространенная и понятная форма математической оптимизации - это линейное программирование, секретная разработка советских инженеров конца 1930-х годов, ставшая популярной в ходе Второй мировой войны. Кстати, слово «программирование» в данном словосочетании является пережитком военной терминологии того времени и не имеет ничего общего с компьютерным программированием.

Начнем с любимого примера экономистов - пушек и масла. Идет 1941-й год, вы – хозяин французской молочной фермы. Днем вы доите коров и производите сливочное масло, ночью – собираете автоматы. Ваша цель – максимальная прибыль, чтобы как можно дольше производить автоматы. От посредника из Сопротивления вы получаете за каждый автомат по 195 денежных единиц (чтобы не напрягать Excel несуществующими франками, допустим, что это доллары). За каждую бочку масла на рынке вам платят по $150.

Условия и ограничения. Себестоимость одной бочки масла – $100, а одного автомата – $150. Месячный бюджет на производство - $1800. Вы храните продукцию в 21-кубометровом подвале. Автомат занимает ½ м 3 , бочка масла 1½ м 3 . Сколько автоматов и бочек масла вам нужно продать за месяц, чтобы получить максимальную прибыль?

Линейная программа определяется как набор решений, необходимый для оптимизации объекта в свете некоторых условий, где и объект, и условия линейны. Вы можете складывать, вычитать, умножать на константы, но не можете применять для решения нелинейные функции, например, перемножение переменных (нельзя автоматы умножить на масло), возведение в квадрат или логические циклы, такие как ЕСЛИ.

Представим области допустимых значений графически. Во-первых, количество пушек и бочек масла должно быть неотрицательным. Во-вторых, максимально можно произвести $1800/$150 = 12 автоматов или $1800/$100 = 18 бочек масла (рис. 1). Общее название этого треугольника – политоп – фигура с плоскими сторонами (например, бриллиант). В-третьих, подвал может вместить не более 21/(½) = 42 автоматов или 21/(1½) = 14 бочек масла (рис. 2).

Чтобы найти идеальное соотношение автоматов и бочек введем в задачу понятие линии уровня функции . Такая линия в оптимизационной модели включает значения, приносящие одинаковую прибыль. Линию уровня можно задать уравнением:

(195 – 150) * N автоматов + (150 – 100) * N бочек масла = С,

где С – константа.

Например, при С = 450, линия будет проходить через координаты (0;10) и (9;0). Графически идея максимизации прибыли реализуется перемещением линии уровня параллельно самой себе в направлении увеличения значений по осям Х и Y (рис. 3). Любопытно, что для политопа оптимум всегда лежит в одной из вершин (или единственного решения не существует вовсе). На этом свойстве основан алгоритм симплексного метода. Решение задачи в Excel начинают с создания области модели (рис. 4). Формула целевой функции в ячейке В1 =СУММПРОИЗВ(C4:D4;C10:D10).

Рис. 3. Линия уровня и функция для оптимизации прибыли: а) некое произвольное начальное положение; б) линия уровня в оптимальном положении

У вас всё готово, чтобы нажать кнопку ДАННЫЕ –> Поиск решения . (Если вы не видите этой кнопки, установите надстройку Поиск решения; см. , глава 1). В открывшемся окне Параметры поиска решения задайте выделенные опции и нажмите Найти решение .

Рис. 5. Окно Поиск решения

Excel обновит лист и внесет на него результаты расчета (рис. 6).

Что произойдет, если добавить нелинейность? Допустим ваш посредник предлагает $500, если число автоматов в месяц будет более 5. Просто добавьте функцию ЕСЛИ в ячейку с прибылью (В1). Теперь целевая функция выглядит так: =СУММПРОИЗВ(C4:D4;C10:D10)+ЕСЛИ(C4>5;500;0). Жмем Поиск решения . Неудача, Excel сообщает об ошибке – условия линейности не выполнены (рис. 7).

Можно попробовать эволюционный алгоритм, лучше всего работающий с нелинейными моделями, и практически не ограничивающий вас в выборе функций. Работа эволюционного алгоритма в чем-то повторяет принципы работы биологической эволюции:

  • генерирует пул исходных решений (что-то вроде генетического пула) разной степени вероятности;
  • каждое решение имеет некий уровень пригодности к выживанию;
  • решения размножаются перекрестным переносом, то есть их компоненты выбираются из двух или трех существующих решений и затем комбинируются;
  • существующие решения мутируют в новые;
  • имеет место локальный поиск, в процессе которого генерируются новые решения вблизи лучшего на данный момент решения в популяции;
  • происходит отбор: случайно выбранные неуспешные кандидаты в решения выбрасываются из генетического пула.

К сожалению, с эволюционным алгоритмом все же возникают некоторые проблемы:

  • Время работы существенно больше, чем при симплекс-методе
  • Нет никакой гарантии, что он найдет оптимальное решение. Все, что в его силах - это контроль лучшего решения в популяции, пока не закончится время, либо популяция не изменится в достаточной степени для продолжения, либо вы принудительно не остановите «Поиск решения» нажатием кнопки ESC.
  • Эволюционный поиск решения работает довольно медленно. А если области допустимых значений сложные, он часто ругается, не найдя даже места, с которого начать.
  • Если вы хотите заставить эволюционный алгоритм хорошо работать в Excel, вам придется определить жесткие границы для каждой переменной решения. Даже если ваше решение более или менее неограниченное, вам все же нужны ограничения.

Принимая во внимание последний пункт, для решения задачи с автоматами и маслом вам нужно добавить ограничение, согласно которому оба решения не должны быть больше 25 (рис. 8). Установив основные параметры модели, кликните на кнопку Параметры . Проработав около минуты, эволюционный алгоритм выдал ожидаемое решение – 6 автоматов и 9 бочек масла. Поскольку без бонуса оптимально сделать лишь три автомата, а бонус выплачивается при производстве более 5 автоматов, очевидно, что оптимальным будет выбор 6 автоматов.

Рассмотрим теперь более сложный пример. Вы работаете в компании, которая производит апельсиновый сок, смешивая натуральные соки разных сортов (рис. 9). Чтобы ваш сок отвечал самым изысканным требованиям:

  • отношение по шкале Брикс/кислотность должно оставаться в пределах 11,5–12,5;
  • уровень кислотности должен оставаться между 0,75–1%;
  • уровень вяжущего вкуса должен быть 4 или ниже;
  • цвет должен находиться в рамках 4,5–5,5.

Шеф сообщил вам, что на январь и февраль он ожидает спросу на уровне 600 000 галлонов сока в месяц, а в марте – 700 000 галлонов. И еще, имеется договор со штатом Флорида, предоставляющий налоговые льготы при условии, что компания покупает не менее 40% сока каждый месяц у фермеров, выращивающих сорт Valencia . Договор следует соблюсти.

Рис. 9. Список характеристик для производства свежевыжатого апельсинового сока (чтобы увеличить изображение, кликните на нем правой кнопкой мыши, и выберите Открыть картинку в новой вкладке )

Создайте оптимизационную модель (рис. 10). Формулы можно изучить на соответствующем листе, приложенного Excel-файла. Кликните Поиск решения , и введите параметры (рис. 11). Нажмите Найти решение .

Рис. 11. Заполненное окно Поиск решения для задачи смешивания

Запустив Поиск решения , вы находите оптимальную стоимость закупок - $1,23 млн. (рис. 12). Обратите внимание, что заказ флоридской Valencia проходит по нижней границе условия. Очевидно, эта сделка - не лучший вариант, но приходится смириться. Второй по популярности сорт - это Verna из Мексики, которая чертовски дешева, но ровно настолько же ужасна.

Вы представляете результаты расчета шефу, но он остается недоволен, и говорит о том, что не хочет выходить за бюджет $1,17 млн. Вы возвращаетесь к компьютеру и начинаете понимать, что стоимость перестала быть целевой функцией. Теперь это условие! А какова цель? Вы можете снизить стоимость закупок только смягчив требования к качеству. Вы решаете сформулировать их в терминах процентного сокращения, и делаете новую модель (рис. 13).

Обратите внимание, что в ячейках В26:29 и F26:F29 теперь не константы, а формулы. Ваша новая цель – минимизация процента снижения качества в ячейках G26:G29. Точнее, вы бы хотели минимизировать максимальное из значений в ячейках G26:G29. Однако, если в ячейку D2 поместить формулу =МАКС(G26:G29), модель не будет работать. Напоминаю, функция МАКС не является линейной. Здесь доступна маленькая хитрость – можно внести дополнительное условие в модель: $G$26:$G$29<=$D$2 (рис. 14), а ячейку D2 оставить пустой. Т.е., ячейка D2 будет оптимизироваться не благодаря наличию в ней формулы, а последовательными циклами, запускаемыми этим дополнительным условием.

Нажмите Найти решение . Симплексный алгоритм будет пытаться приблизить D2 к 0 как целевую функцию модели, в то время как ограничения по вкусу и цвету будут пытаться увеличить ее насколько возможно, чтобы получить пригодную для работы смесь. Где же остановится значение D2? Самое меньшее из возможных значений - максимальный процент из четырех сниженных в диапазоне G26:G29. Мы видим (рис. 15, ячейки С26:Е29), что снижение расходов на 5% потребовало выйти за ограничения качества по всем четырем параметрам.

Вы представили данные шефу, который увидел, что сокращение расходов на 5% не стоит снижения качества сока, поэтому он согласовал ваш первый вариант. Но, когда вы принесли его в отдел снабжения, сотрудники возмутились. Как можно было так раздробить поставки!? Снабженцы настаивают, чтобы вы укрупнили партии: не более 4 поставщиков ежемесячно! И вы садитесь за новую модель. К сожалению, использовать функции ЕСЛИ или СЧЁТ вы не можете, так как хотите остаться в рамках линейной модели. Поэтому вам снова приходится прибегнуть к ухищрениям (рис. 16). Вы добавляете в модель область С33:Е43, которую определяете, как бинарную (значения в ней могут быть только 0 или 1), и оставляете ее пустой. А также область F33:H43, где каждая ячейка равна произведению значения из областей С33:Е43 на G5:G15. В параметры Поиск решения (рис. 17) вы добавляете еще одно условие $С$15:$Е$15 <= $F$33:$H$43 и еще одну область переменных – $C$33:$E$43.

Как в этом случае будет работать оптимизационный алгоритм? Когда он стартует все значения в областях С5:Е15, С33:Е43 и F33:H43 равны нулю. Допустим, что алгоритм пытается в ячейку С7 поместить значение 240. Сработает условие С7 <= F35, которое приведет к увеличению значения в F35, которое, в свою очередь, определяется формулой F35 = C35*$G7. Поскольку G7 – константа, а С35 – бинарная переменная, последней присваивается значение 1. Условие С7 <= F35 выполнено, т.к., 240 <= 1200. Таким образом вы моделируете неудобное условие «если… то»: «если заказ сделан, то бинарная переменная включается».

Нажмите Найти решение . Вы заметите, что решение задачи требует больше времени из-за добавления бинарных переменных. Если по какой-то причине Поиск решения слишком затянул свой поиск, вы всегда можете нажать ESC и увидеть лучшее из найденных решений на данный момент.

В принципе, вы уже довольно продвинутый специалист в области линейного программирования. Но, если вы вошли во вкус, и вам нравится разбираться с моделями всё возрастающей сложности, вот вам еще два зубодробительных примера.

Инженеры сообщили, что на производстве появились новые «снижатели кислотности». Данная технология способна нейтрализовать 20% кислоты в соке, протекающем через прибор. Это не только снижает процент кислоты, но и повышает индекс Брикс/кислотность на 25%. Но для «снижателя» нужна энергия и расходные материалы стоимостью $20 за 1000 галлонов сока. Не весь сок, поступающий от поставщиков, нужно прогонять через этот процесс, однако, если поставка по какому-нибудь заказу прогоняется через ионообменник, то должен быть обработан весь ее объем. Постройте модель с участием ионообменника для снижения стоимости.

Проблема с новым правилом заключается в том, что естественный способ его моделирования - нелинейный, что приведет к использованию медленного алгоритма оптимизации. Но, как и в предыдущем примере, можно ввести бинарную переменную в области С25:Е35, которая бы «включалась» при необходимости понизить кислотность партии (рис. 18). Поскольку, нельзя использовать произведение «индикатор понижения кислотности (бинарный) * объем партии», вы создаете область С37:Е47, которая вам пригодятся для уравнивания объемов, подлежащих снижению кислотности, без прямого участия в формулах самих этих объемов. Итак, области С25:Е35 и С37:Е47 не содержат формул. В области G25:I35 используются формулы =С25:Е35*G5:G15 (это ограничение партии общим доступным объемом сока), а в области К25:М35 =Е5:E15-GG5:15*(1-Е25:E35). Это условие заработает только если партия подлежит снижению кислотности.

Также в модели со «снижателем кислотности» были изменены формулы в ячейках С16:Е16 (теперь они учитывают затраты на снижение кислотности по формуле «индикатор (бинарный) * объем партии * $20) и в ячейках С50:Е51 (теперь они учитывают повышение коэффициента Брикс/кислотность на 25% и снижение кислотности на 20% для обработанных партий). В параметрах Поиска решения появились новые переменные и дополнительные условие (рис. 19). К сожалению, нажав кнопку Найти решение , вы узнаете, что надстройка Поиск решения не может справиться с задачей (рис. 20). Модель стали слишком сложной.

Рис. 19. Параметры Поиска решения в модели со «снижателем кислотности»

Рис. 20. Поиск решения не справляется с задачей

Вам нужно загрузить и установить OpenSolver (как это сделать см. , глава 1). OpenSolver «подхватит» установки, введенные только что в окне Поиск решения . Поэтому просто нажмите кнопку Solver . Полученное решение – $1 235 927 более чем на $ 100 000 лучше предыдущего минимума – $1 338 913.

До сих пор мы считали, что поставляемая продукция имеет точно указанные параметры. Резонно предположить, что эти параметры подвержены вариации, характеризуемой среднеквадратичным отклонением (рис. 21; подробнее см. ). Самое известное и широко используемое распределение случайной величины - это нормальное распределение, иначе называемое «колоколообразной кривой». Скажем, в случае с соком из Египта среднее значение отношения Брикс/кислотность будет 13, а среднеквадратичное отклонение (также называемой стандартным отклонением) - 0,9 (рис. 21). В данном примере 13 - это центр распределения вероятности, 68% заказов будут в пределах ±0,9 от 13, а 95% будут в пределах ±1,8 от 13.

Ваша цель - предложить план смешивания стоимостью меньше $1,25 миллиона, который наилучшим образом соответствует ожиданиям по качеству в свете вариабельности поставок.

Мы используем среднее и среднеквадратичное отклонение характеристик, чтобы применить имитационное моделирование по методу Монте-Карло (если вы слышите это название впервые, рекомендую ). В этом методе вместо включения параметров распределения (среднего значения и среднеквадратичного отклонения) в модель напрямую, создается большое число сценариев, основанных на этих самых параметрах распределения.

Сценарий - это один из возможных ответов на вопрос: «Если это - распределения, основанные на статистике, на что же будет похож конкретный заказ?» Каждый сценарий включает сорок параметров десяти сортов сока (рис. 22). Чтобы получить один такой параметр, воспользуйтесь функцией НОРМ.ОБР (подробнее о функции см. ). Например, в ячейке В33 отношение Брикс/кислотность для сорта Hamlin определяется формулой =НОРМ.ОБР(СЛЧИС();H5;N5). Введите аналогичные формулы в область В33:СW76, сгенерировав 100 сценариев. Поиск решения не сможет работать с этими формулами, так как они нелинейны, поэтому скопируйте их в буфер и вставьте, но уже, как значения.

Цель минимизировать значение в ячейке D2. Т.е., найти решение, которое менее всего снижает границы качества для 100 сценариев. Как и в примерах на рис. 13–15, в ячейке D2 нет формулы. Оптимизация выполняется заданием параметров в окне Поиск решения. Все, что нужно - это поместить во все сценарии границы качества, а не просто ожидаемые значения характеристик. Таким образом, в отношение Брикс/кислотность вы добавляете условия B78:CW80 >= B26 и =< F26, затем проделываете то же самое с кислотностью, вяжущей составляющей вкуса и цветом (рис. 24). Нажмите Найти решение . Решение найдется довольно быстро. Если вы генерировали случайные значения сами, а не использовали те, что находятся в файле для загрузки, ваше решение может отличаться. Для моей сотни сценариев наилучшим показателем, который мне удалось получить, является изменение качества на 133%.

Рис. 24. Настройка Поиска решения для модели с вариабельностью характеристик

Если вы хотите расширить свои знания в области линейного программирования, рекомендую книгу The AIMMS optimization modeling book . Не пропустите две главы про трюки и подсказки – они поистине гениальны.

Написано по материалам книги Джона Формана . – М.: Альпина Паблишер, 2016. – С. 129–186. Насчет секретности разработки и Второй мировой – это, похоже, личное мнение автора книги. См. Википедию . – Прим. Багузина .

Каждый пользователь сталкивался с тем, что иногда в Excel не найти подходящих инструментов, которые бы соответствовали потребностям. При всем изобилии возможностей Excel иногда нельзя автоматизировать решения некоторых задач, ведь совершенству нет предела. Идеальное решение – это предоставление возможности пользователю самому создавать свои специфические инструменты. Для этого были созданы макросы.

Написание макросов в Excel

Код макроса Excel написанный на языке Visual Basic for Application (VBA), а его выполняет инструмент приложения, к которому он присоединен. Большинство этих инструментов не доступно на уровне окна программы Excel. Как написать макрос.

Теперь продемонстрируем на примере информацию о том, как писать, редактировать и выполнять код макроса.

Чтобы написать макрос:


Примечание. Если в главном меню отсутствует закладка «РАЗРАБОТЧИК», тогда ее необходимо активировать в настройках: «ФАЙЛ»-«Параметры»-«Настроить ленту». В правом списке «Основные вкладки:» активируйте галочкой опцию «Разработчик» и нажмите на кнопку ОК.



Возможности макросов в Excel

Макросы позволяют автоматизировать процессы работы с документами и не только… Они могут практически одновременно выполнить тысячи инструментов за одну операцию (даже по одному клику мышкой). Таким образом расширяются возможности работы с программой.

С помощью макросов пользователь может сам создать свой инструмент, которого ему недостает в арсенале программы Excel. Например, когда нужно автоматически выделить каждую вторую строку одним кликом. Или нужно одновременно создать сразу определенное количество копий определенного рабочего листа. Список потребностей пользователей в автоматизации процессов работы можно продолжать до бесконечности.

Если бы не было возможности создавать макросы во всех программах, входящих в пакет MS Office. То множество операций в процессе рутинной работы пользователям приходилось бы выполнять вручную (выделять через одну строку кликая по каждому второму заголовку мышкой или копировать вставлять по одному листу). Ручная работа в лучшем случаи приводить к потере огромного количества времени, а в худшем – ведет к ошибкам или даже потере ценных данных.

Возможность создавать макросы и автоматизировать рабочие процессы бережет вашу работу от лишних потерь времени и возникновения ошибок. Далее рассмотрим, как создать макрос, который безошибочно и автоматически выполнить рутинную работу в один клик мышкой. Так же рассмотрим в каких местах рабочей книги Excel можно создавать и хранить макросы. Как их запустить и выполнить, а также как их максимально оптимизировать под свои потребности.

Excel предоставляет большой и изобильный арсенал инструментов для хранения и обработки огромного количества информации с данными. Хотя для самой универсальной аналитической программы Excel – хранение данных само по себе менее интересно, чем возможность их обрабатывать, структурировать и анализировать с презентацией в отчетах. Для этих целей служит сильнейший аналитических инструмент по обработке данных такой как «Сводные таблицы». Но и его можно еще более усовершенствовать с помощью макросов. И тогда возможности сводных таблиц не знают границ.

Excel 2000".

Почему не просто "Мир Excel 2000"? Видимо, потому что я предпочитаю смотреть на все, что происходит в Excel , с объектной точки зрения, рассматривать все происходящее как действия над объектами. Да и описанию самих объектов в этой книге уделяется достаточно много внимания. При этом в круг рассмотрения входят не только объекты самого Excel . Мир объектов Excel более широк. Так или иначе, в рассмотрении появляются общие объекты Office 2000, объекты других приложений, в книге, например, много внимания уделяется связи Excel и Access. Помимо объектов Excel в книге подробно рассматриваются еще две группы объектов - ADO и OWC. Объекты ADO , позволяющие организовать доступ к базам данных, несомненно, входят в мир Excel , поскольку, чаще всего, Excel является тем приложением, где обрабатываются данные, хранимые в различных источниках. Компоненты OWC, обладающие функциональностью Excel , - их объектная модель - это тоже часть мира объектов Excel . Без этих объектов не обойтись, если Ваше решение переносится в интранет или интернет , и Вы захотите создать Web -узел, страницы которого обладают функциональностью Excel документов.

Что же можно найти в этой книге, и кому она предназначена?

Эта книга предназначена тем, кто создает решения на базе Excel . Конечно, в первую очередь речь идет о тех, кто уже использует программирование на VBA и VBScript при создании своих решений. Но я думаю, что и те, кто давно работает в Excel , но еще не использовал программные способы настройки своих решений, могут начать с этой книги, хотя, предупреждаю, требуется определенная программистская подготовка.

Первые две лекции посвящены началам программирования в Excel . Они, надеюсь, доступны опытным пользователям и начинающим программистам. Думаю, что их с интересом прочтут и те, кто занимается обучением программированию в любой среде программирования. Я высказываю и пытаюсь обосновать здесь "крамольную" мысль о том, что Excel является прекрасной средой начального обучения программированию в школе и в вузах. Надеюсь, что и опытные программисты найдут здесь кое-что полезное для себя, особенно, во второй главе, адресованной математикам.

Глава 3 дает описание объектной модели Excel . Подробно рассмотрены все основные действующие лица этой модели - объекты Application , WorkBook, WorkSheet, Chart , Range и другие. Понятно, что при раскрытии этой темы без технических деталей не обойтись, поэтому чтение главы довольно утомительно, но как справочный материал, она, надеюсь, будет весьма полезной.

Базы данных и другие источники данных - это одна из ведущих тем этой книги. Глава 4 " Excel и базы данных " начинает эту тему. В этой же главе дается знакомство с приложением Access, на примере показано, как строится база данных в Access, изучаются связи Excel и Access.

Пятая и шестая главы книги посвящены объектам ADO . Уже то, что этим объектам посвящены две главы, говорит о степени подробности рассмотрения этой темы. Объекты ADO задают интерфейс между самыми разнообразными источниками данных и клиентским приложением, где эти данные обрабатываются. Таким приложением совсем не обязательно должен быть Excel , сфера применения объектов ADO значительно шире. Но Excel это одна из наиболее подходящих кандидатур на роль такого клиентского приложения. Чтение этих глав требует определенной подготовки и ориентированно на более продвинутых программистов.

Седьмая глава книги посвящена разработке интерактивных документов. Она носит в определенном смысле центральный характер. В ней рассматривается весь процесс создания интерактивного документа Excel . Этот документ можно считать примером создаваемого в Excel типичного решения, в котором программный проект играет определяющую роль. Предлагаемое решение использует базу данных Access и объекты ADO для организации связи с базой данных. Здесь же обсуждается и ряд других вопросов, важных в практической работе, начиная от организации интерфейса пользователя до получения печатной формы документа.

Глава 8 посвящена вопросам, возникающим при анализе офисной деятельности. В ней делается попытка сочетать содержательное рассмотрение, например, рассмотрение того, как проводить анализ типа "Что, если …" с рассмотрением средств Excel , используемых в таком анализе. Здесь рассматриваются сводные таблицы и сводные диаграммы, сценарии , методы прогнозирования и многое другое.

В девятой главе подробно обсуждается создание проекта под названием "MasterF". С содержательной точки зрения рассматривается задача оптимального выбора инвестиционных вложений. В проектном решении используется мощный встроенный инструмент Excel - решатель Solver, позволяющий решать сложные оптимизационные задачи. Данный проект демонстрирует построение надстройки над встроенным инструментарием Excel . Полагаю, что он может иметь не только учебную, но и практическую ценность для тех, кто решает подобные задачи.

В главе 10 в рассмотрение вводятся новые объекты, тесно связанные с Excel . В этой главе рассматриваются Office Web Components - компоненты OWC. По моему мнению, эти компоненты являются лучшим продуктом, созданным Microsoft в области компонентного программирования. Они дают возможность добавить функциональность Excel в свои решения без использования самого Excel и других приложений Office 2000. Основное предназначение этих компонент - обеспечение корпоративной работы с документами в интрасетях, что позволяет создавать интерактивные страницы Web -узлов, обладающие функциональностью Excel . При рассмотрении этих компонент большое внимание уделяется программной работе с этими компонентами, возможности программной настройки Web -документов, использующих эти компоненты.

Глава 11 посвящена введению в Web - программирование . Я подробно рассматриваю процесс создания интерактивного Web -документа. Ключевым словом здесь является " интерактивность ", поскольку, по большому счету, вся эта книга о том, как придать нужную интерактивность создаваемым документам. Глава носит вполне самостоятельный характер, но, по сути, является естественным продолжением двух тем, рассматриваемых в главах 7 и 10, поскольку с одной стороны речь идет о создании интерактивного документа, с другой - документа Web , страницы которого могут обладать функциональностью Excel . Замечу, что при рассмотрении вопросов создания интерактивного очередь , на школьников, но не только на них. Большинство игр относится к классу "развивающих" игр, направленных на развитие логического мышления. Среди игр есть вариации известных игр - Lines, Tetris, Digger, игры-головоломки, известная карточная игра "Подкидной дурак" и другие игры.

Завершая предисловие, хочу сказать, что предлагаемый курс тесно связан с книгами серии "Офисное программирование ", вышедшими в издательстве "Русская редакция". Есть явные и неявные ссылки в тексте многих глав:

  1. "VBA в Office 2000. Офисное программирование,
  2. "Средства разработки VBA-программиста". Офисное программирование,
  3. Мир объектов Excel 2000. Средства разработки VBA-программиста.

Хорошо, если читатели знакомы с этими книгами, или прошли курсы по первым двум книгам, но это не обязательное требование. Пройти данный курс можно вполне самостоятельно. Скажу даже, что я старался, по возможности, сделать каждую главу доступной для независимого чтения.

Просьба к читателям. Поскольку курс построен на основе ранее вышедшей книги и практически не подвергался переделке, то возможны "висячие ссылки", имеющие смысл только для книги. Часть материала уже устарела. Постарайтесь быть снисходительными к этим огрехам. Я искренне верю, что основное содержание не потеряло своей ценности и может быть полезным всем, кто так или иначе связан с офисным программированием.