Количество рабочих и выходных дней в месяце с сайта its.1c.ru

Простенькая функция, которая обращается к сайту ИТС и возвращает оттуда сведения о количестве рабочих дней в указанном месяце.
Платформа 8.3.10, УФ.

Понадобилось для своей конфигурации тупо посмотреть, сколько рабочих дней было в месяце. Заводить из-за этого свой или подключать БСП-шный календарь, графики рабочего времени с учётом переносов выходных и праздников, обеспечивать их актуальность — 8 килограмм проблем — лень.

Вот и решил сделать такую простенькую функцию, которая ходила бы на сайт ИТС и оттуда бы забирала эти данные, благо они в открытом доступе…

Функция делает простое обращение по https к сайту ИТС (its.1c.ru) и забирает оттуда информацию, связанную с календарём бухгалтера. Так как эта информация лежит в открытом доступе, логин и пароль к сайту ИТС не требуется. В качестве страницы, к которой происходит обращение, указывается путь /calendar/YYMM. Выполняется простой парсинг полученного ответа: находятся строки, содержащие текст "Календарных дней", "Рабочих дней", "Рабочих часов", "Выходных и праздничных дней". Если на сайте нет информации о каком-либо месяце, то и ответ будет невразумительный. Например, на сегодняшний день (22.11.2024) доступны сведения о календаре бухгалтера с декабря 2011 года по декабрь 2024 года. Видимо, более ранних сведений просто нет, а календарь на следующий год ИТС-ники пока не удосужились ввести на сайт. В этом случае функция выдаст ошибку, в возвращаемой структуре будут нули. Чтобы избежать ошибок, если они существуют на сайте (да-да, челофактор повсюду!), сделаны простенькие проверки. Ну, сами посмотрите, всё прозрачно.

Косячки немножко есть, знаю — фукнцию можно легко оптимизнуть, не судите строго.

Пользуйтесь на здоровье, мало ли кому пригодится.

Вот как-то так:

// Сведения о нужном месяце с сайта ИТС.
// Параметр - сам месяц в формате даты (год тоже нужен).
// Возвращаемое - структура с числовыми полями:
//   КолвоКалендарных
//   КолвоРабочих
//   КолвоВыходных
//   КолвоРабочихЧасов
// если что-то не так, - в возвращаемых значениях "0".
&НаКлиенте
Функция ПолучитьКалендарныеДанныеСайтаИТС(Мес)
// Соединение устанавливаем по HTTPS, иначе не работает:
Соед = Новый HTTPСоединение("its.1c.ru", 443,,,,, Новый ЗащищенноеСоединениеOpenSSL(Новый СертификатКлиентаWindows(СпособВыбораСертификатаWindows.Авто), Новый СертификатыУдостоверяющихЦентровWindows()),);
// Сформируем нужную папку для запроса, добавим в правильном формате месяц и год:
ВебЗапр = Новый HTTPЗапрос("calendar/"+Формат(Мес,"ДФ=yyMM"));
// Пробуем достучаться до сервера:
Попытка
Результат = Соед.Получить(ВебЗапр);
Исключение
Сообщить("Ошибка соединения: Что-то не так с обращением к сайту its.1c.ru. Возможно, сервер недоступен. Или что-то с интернетом.");
ВызватьИсключение;   // Ну пусть пока так будет...
КонецПопытки;
// До сервера может и достучалось, но какие-то проблемы со страницей:
Если Результат.КодСостояния >= 300 Тогда
Сообщить("Ошибка: Что-то не так с обращением к странице. Возможно, календарь бухгалтера для этого месяца не определён.");
ДанныеМесяца = новый структура;
ДанныеМесяца.Вставить("КолвоКалендарных", 0);
ДанныеМесяца.Вставить("КолвоРабочих", 0);
ДанныеМесяца.Вставить("КолвоВыходных", 0);
ДанныеМесяца.Вставить("КолвоРабочихЧасов", 0);
Возврат ДанныеМесяца;
КонецЕсли;
// Пока всё норм, получаем текст страницы. Просто для удобства:
Резуль = Результат.ПолучитьТелоКакСтроку();
// Находим нужные позиции (они могут идти и не в такой последовательности!!!):
ПозКД = СтрНайти(Резуль, "Календарных дней");             // Календарных дней
ПозРД = СтрНайти(Резуль, "Рабочих дней");                 // Рабочих дней
ПозВД = СтрНайти(Резуль, "Выходных и праздничных дней");  // Выходных дней
ПозРЧ = СтрНайти(Резуль, "Рабочих часов");                // Рабочих часов при 40-часовой рабочей неделе - убить их мало: то ошибку в строке сделают, то дефис забудут... Ну... Чем богаты.
// Периодически они после цифр втыкали лишний пробел, поэтому на всякий случай "СокрЛП", см., напр, март 2024. Считаем концом строки текст "<br>":
Если ПозКД Тогда КвоКД = СокрЛП(Сред(Резуль, ПозКД+19, СтрНайти(Резуль, "<br>", , ПозКД) - (ПозКД + 19))); Иначе КвоКД = "0"; КонецЕсли;
Если ПозРД Тогда КвоРД = СокрЛП(Сред(Резуль, ПозРД+15, СтрНайти(Резуль, "<br>", , ПозРД) - (ПозРД + 15))); Иначе КвоРД = "0"; КонецЕсли;
Если ПозВД Тогда КвоВД = СокрЛП(Сред(Резуль, ПозВД+30, СтрНайти(Резуль, "<br>", , ПозВД) - (ПозВД + 30))); Иначе КвоВД = "0"; КонецЕсли;
Если ПозРЧ Тогда КвоРЧ = СокрЛП(Сред(Резуль, ПозРЧ+46, СтрНайти(Резуль, "<br>", , ПозРЧ) - (ПозРЧ + 46))); Иначе КвоРЧ = "0"; КонецЕсли;
// Ну пробуем, чо:
Попытка ККД = Число(КвоКД); Исключение ККД = 0; КонецПопытки;
Попытка КРД = Число(КвоРД); Исключение КРД = 0; КонецПопытки;
Попытка КВД = Число(КвоВД); Исключение КВД = 0; КонецПопытки;
Попытка КРЧ = Число(КвоРЧ); Исключение КРЧ = 0; КонецПопытки;
// Структура с данными:
ДанныеМесяца = новый структура;
ДанныеМесяца.Вставить("КолвоКалендарных", ККД);
ДанныеМесяца.Вставить("КолвоРабочих", КРД);
ДанныеМесяца.Вставить("КолвоВыходных", КВД);
ДанныеМесяца.Вставить("КолвоРабочихЧасов", КРЧ);
// Возвращаем:
Возврат ДанныеМесяца;
КонецФункции

В обработке в качестве примера всё реализовано целиком.

5 Comments

  1. 🅵🅾️🆇

    На вскидку небольшие придирки:

    Скрытый текст
    Reply
  2. 🅵🅾️🆇

    (1) Также очень бы рекомендовал разбирать HTML страницу через DOM, это будет и быстрее и точнее и не будет: «// убить их мало».

    Если не умеете, то советую быстренько пройти последние модули по JS на SoloLearn (все бесплатно, есть приложение на ведроид), займет час максимум, но качество возрастет в разы. Я этому научился сидя на, пардон, унитазе со смартфона :3 В общем это просто необходимый момент для парсинга. И таким образом можно было бы разобрать не примечание снизу, а сам календарь-таблицу, получая описания для каждого дня.

    Reply
  3. simplysimply

    (2)

    Спасибо, посмотрю.

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

    Reply
  4. 🅵🅾️🆇

    (4) Если очень кратенько, то вам жизнено необходимо научиться делать примерно так:

    Массив1 = Элементы.ПолеHTML.document.getElementsByTagName(«div»);
    Массив2 = Элементы.ПолеHTML.document.getElementsByClassName(«myClass»);
    Элемент = Элементы.ПолеHTML.document.getElementById(«myID»);
    

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

    Еще есть такое:

    ЧтениеHTML = Новый ЧтениеHTML;
    ЧтениеHTML.ОткрытьФайл(АдресСсылки, «windows-1251»);
    ПостроительDOM = Новый ПостроительDOM;
    ДокументHTML = ПостроительDOM.Прочитать(ЧтениеHTML);
    ЭлементыDOM = ДокументHTML.ПолучитьЭлементыПоИмени(«div»);
    // ПолучитьЭлементПоИдентификатору(«id»)
    Для Каждого ЭлементDOM Из ЭлементыDOM Цикл
    …
    КонецЦикла;
    

    Показать

    Ну и все в таком духе :3

    PS: мог в синтаксисе гденить немног абшибиться, но идея в целом такая)

    1с не так силен в парсинге-скрапинге, как скажем, Python библиотека lxml. Но в целом и им можно добиться очень неплохих результатов и разобрать очень многое.

    Reply
  5. simplysimply

    (5)

    Спасибо.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *