Да, вот и наступило время, когда можно описать задачу и ИИ сам напишет код! Почти. Если раньше за подобную задачу и браться не хотелось, потому что ради одноразовой утилиты нужно было потратить часы на чтение мануалов, на пробы и ошибки, отладку, поиск правильных подходов и функций, то теперь вот так просто. Конечно все еще не настолько хорошо, все еще нужно понимать основы программирования чтоб довести код что выдает ИИ до ума, но уже реально большая часть кода пишется именно ИИ! От программиста требуется лишь понимание самых основ, вроде ветвлений, циклов, переменных — а синтаксис, нужные функции и некоторые приемы использования уже может взять на себя ИИ.
Изначальная задача — получить нечто вроде расчерченного календаря в Excel, где будут дни недели, числа и ячейки для заполнения по дням. Задача была поставлена максимально на языке программистов, но без знания самого языка VBA и как им пользоваться в Excel:
Напиши макрос для Excel который перебирает даты с 01.01.2023 до 31.12.2023 в переменной D. Внутренний цикл идет по 7 дней, заполняя ячейки названием дней недели в сокращенной форме Пн-Вс в соответствии с датой в D а также в ячейке ниже — число месяца, и на каждой итерации D+1. Внешний цикл выводит название месяца в строке, если оно отличается от предыдущего месяца.
ChatGPT на это выдал уже в общем рабочий код, который сразу без ошибок работал и чертил нечто вроде календаря:
Sub FillCalendar() Dim startDate As Date Dim endDate As Date Dim currentDate As Date Dim currentMonth As String Dim previousMonth As String Dim dayOfWeek As String ' Установите начальную и конечную даты startDate = DateSerial(2023, 1, 1) endDate = DateSerial(2023, 12, 31) ' Установите начальные значения currentDate = startDate currentMonth = Format(currentDate, "MMMM") previousMonth = "" ' Устанавливаем активный лист Worksheets("Sheet1").Activate ' Очищаем предыдущие данные Cells.Clear ' Устанавливаем начальную позицию для записи данных Dim rowPosition As Integer Dim colPosition As Integer rowPosition = 1 colPosition = 1 ' Внешний цикл для обработки месяцев Do While currentDate <= endDate currentMonth = Format(currentDate, "MMMM") ' Выводим название месяца, если оно отличается от предыдущего If currentMonth <> previousMonth Then Cells(rowPosition, colPosition).Value = currentMonth previousMonth = currentMonth rowPosition = rowPosition + 1 End If ' Внутренний цикл для обработки дней недели For i = 1 To 7 dayOfWeek = Format(currentDate, "ddd") ' Заполняем ячейку с названием дня недели Cells(rowPosition, colPosition).Value = dayOfWeek ' Заполняем ячейку с числом месяца Cells(rowPosition + 1, colPosition).Value = Format(currentDate, "d") colPosition = colPosition + 1 currentDate = currentDate + 1 Next i ' Переходим на следующую строку rowPosition = rowPosition + 2 colPosition = 1 Loop End Sub
Разметка вышла немного хаотичной — строка начиналась не с понедельника, начальные даты следующего месяца залезали в конец недели предыдущего и никакой подсветки. Но так как ChatGPT оказался способен вносить правки в этот код, то далее можно было отдельно скорректировать некоторые моменты:
1. доработай код чтобы названия месяцев были жирным шрифтом, а дни недели серым. Кроме того ниже ячейки с днем месяца добавляй пустую строку
2. день недели пусть будет не серым шрифтом а серым фоном, к тому же если это Сб или Вс то фон желтый
3. теперь внутри цикла For i = 1 To 7 если месяц в currentDate отличается от месяца currentMonth то нужно пропустить все содержимое цикла. а переменную colPosition вообще нужно убрать и использовать вместо нее i, так будет короче
Далее я захотел чтоб неделя всегда была с понедельника и были пропуски если месяц начиная с другого дня, тут уже я как программист легко добавил еще одно условия, предварительно спросив у ИИ как в VBA получить номер дня недели:
как в макросе из даты получить номер дня недели от 1 до 7 ?
>Вы можете использовать функциюWeekday
, чтобы получить номер дня недели от 1 до 7 на основе даты.
функция Weekday вернет 1 для какого дня недели?
>ФункцияWeekday
вернет 1 для воскресенья (Вс).
А если мне нужно чтоб 1 возвращалось для понедельника а 7 для воскресенья, как мне записать это?
>Чтобы получить номер дня недели от 1 до 7, где 1 соответствует понедельнику, а 7 — воскресенью, вы можете использовать функциюWeekday
с параметромvbMonday
.
После чего я собственно уже дописал еще одну проверку и итоговый скрипт получился такой:
Sub FillCalendar() Dim startDate As Date Dim endDate As Date Dim currentDate As Date Dim currentMonth As String Dim previousMonth As String Dim dayOfWeek As String ' Установите начальную и конечную даты startDate = DateSerial(2023, 1, 1) endDate = DateSerial(2023, 12, 31) ' Установите начальные значения currentDate = startDate currentMonth = Format(currentDate, "MMMM") previousMonth = "" ' Устанавливаем активный лист Worksheets("Лист1").Activate ' Очищаем предыдущие данные Cells.Clear ' Устанавливаем начальную позицию для записи данных Dim rowPosition As Integer rowPosition = 1 ' Внешний цикл для обработки месяцев Do While currentDate <= endDate currentMonth = Format(currentDate, "MMMM") ' Выводим название месяца, если оно отличается от предыдущего If currentMonth <> previousMonth Then Cells(rowPosition, 1).Value = currentMonth Cells(rowPosition, 1).Font.Bold = True ' Жирный шрифт previousMonth = currentMonth rowPosition = rowPosition + 1 End If ' Внутренний цикл для обработки дней недели For i = 1 To 7 If Format(currentDate, "MMMM") = currentMonth Then dayOfWeek = Format(currentDate, "ddd") If i = Weekday(currentDate, vbMonday) Then ' Заполняем ячейку с названием дня недели Cells(rowPosition, i).Value = dayOfWeek ' Проверяем, является ли день Субботой (Сб) или Воскресеньем (Вс) If dayOfWeek = "Сб" Or dayOfWeek = "Вс" Then Cells(rowPosition, i).Interior.Color = RGB(255, 255, 0) ' Желтый фон Else Cells(rowPosition, i).Interior.Color = RGB(220, 220, 220) ' Серый фон End If ' Заполняем ячейку с числом месяца Cells(rowPosition + 1, i).Value = Format(currentDate, "d") currentDate = currentDate + 1 End If End If Next i ' Переходим на следующую строку rowPosition = rowPosition + 3 colPosition = 1 Loop End Sub
Все! Результат работы такого кода ниже:
Итоги:
Это уже конечно не первый скрипт-утилита написанный мной таким образом. Главное — если раньше приходилось взвешивать усилия на ручную работу и усилия на изучение особенностей языка + среды выполнения чтоб решить что будет быстрей и проще, и решение в подобном случае могло быть не в пользу одноразового скрипта, то теперь приходит время когда усилия требуемые для решения таких задач уменьшаются на порядок!