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

Программирование - Практика программирования

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

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

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

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

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

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

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

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

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

Скачать файлы

Наименование Файл Версия Размер
Количество рабочих и выходных дней в месяце с сайта its.1c.ru:
.epf 7,63Kb
22.11.17
0
.epf 7,63Kb Скачать

См. также

Комментарии
1. Plague Fox (A1ice1990) 58 26.11.17 12:41 Сейчас в теме
На вскидку небольшие придирки:

Скрытый текст
2. Plague Fox (A1ice1990) 58 26.11.17 23:34 Сейчас в теме
(1) Также очень бы рекомендовал разбирать HTML страницу через DOM, это будет и быстрее и точнее и не будет: "// убить их мало".
Если не умеете, то советую быстренько пройти последние модули по JS на SoloLearn (все бесплатно, есть приложение на ведроид), займет час максимум, но качество возрастет в разы. Я этому научился сидя на, пардон, унитазе со смартфона :3 В общем это просто необходимый момент для парсинга. И таким образом можно было бы разобрать не примечание снизу, а сам календарь-таблицу, получая описания для каждого дня.
PetrPan; Разумов; simplysimply; Coole; +4 Ответить
4. Сергей Сидоров (simplysimply) 22 27.11.17 07:51 Сейчас в теме
(2)
Спасибо, посмотрю.
На предыдущий коммент - Вы, наверно, абсолютно правы во всех придирках, но функция представляется очень малозначимой, поэтому пост править не буду, пусть уж так.
5. Plague Fox (A1ice1990) 58 27.11.17 09:59 Сейчас в теме
(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. Но в целом и им можно добиться очень неплохих результатов и разобрать очень многое.
Разумов; +1 Ответить
6. Сергей Сидоров (simplysimply) 22 27.11.17 10:33 Сейчас в теме
Оставьте свое сообщение