Да, вот и наступило время, когда можно описать задачу и ИИ сам напишет код! Почти. Если раньше за подобную задачу и браться не хотелось, потому что ради одноразовой утилиты нужно было потратить часы на чтение мануалов, на пробы и ошибки, отладку, поиск правильных подходов и функций, то теперь вот так просто. Конечно все еще не настолько хорошо, все еще нужно понимать основы программирования чтоб довести код что выдает ИИ до ума, но уже реально большая часть кода пишется именно ИИ! От программиста требуется лишь понимание самых основ, вроде ветвлений, циклов, переменных — а синтаксис, нужные функции и некоторые приемы использования уже может взять на себя ИИ.
Изначальная задача — получить нечто вроде расчерченного календаря в 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
Все! Результат работы такого кода ниже:

Итоги:
Это уже конечно не первый скрипт-утилита написанный мной таким образом. Главное — если раньше приходилось взвешивать усилия на ручную работу и усилия на изучение особенностей языка + среды выполнения чтоб решить что будет быстрей и проще, и решение в подобном случае могло быть не в пользу одноразового скрипта, то теперь приходит время когда усилия требуемые для решения таких задач уменьшаются на порядок!
