На одном проекте - клиент попросил отображать в программе данные, которые выдаю специализированные сайта в формате RSS - Что делать !?
Писать парсер rss для 1С
Первым делом, взглянув на ссылки, подумал что - обычный XML, сейчас его разложу и быстренько загружу в базу, но:
Выяснилось что сайты имеют разные форматы ввода RSS и главное они не валидные(
таким образом, написав небольшой код, который получает ссылку, далее XMLФайл.Прочитать() на одном сайте проходил на ура (этот пример я описывал в статье: Чтение данных с сайта в формате XML и загрузка в 1С), а вот второй сайт, и третий тоже, при попытке прочитать() выдавали:
{ОбщийМодуль.РегЗадания.Модуль(79)}: Ошибка при вызове метода контекста (Прочитать)
Пока XMLФайл.Прочитать() Цикл
по причине:
Ошибка разбора XML: - [1,1]
Фатальная ошибка:
Extra content at the end of the document
SystemId url rss
решил попробовать на rss других известных сайтов - 80% из проверяемых выдавали ошибку
Пришлось написать прямой построчный парсер RSS:
Структура конфигурации
ИсточникиRSS - URL на RSS, ДанныеRSS - сюда записываются загруженные данные новостей
Код получился таким(в принципе код универсальный, но возможно что-то придется подпилить):
Недавно, мой постоянный клиент решил проводить маркетинговые исследования по изменению цен на товары у конкурентов... и эти данные захотел использовать в 1С в связке с его прайс-листом + куча отчетов с графиками и процентным отклонением от цен основного конкурента
В результате этого, была написана обработка собирающая данные со страниц разных сайтов. Из целей конфиденциальности - сайты раскрывать не буду...
Вид обработки загрузки данных с сайта в 1С
Ниже код загрузки данных со страницы сайта, смысл такой :
в функция передается адрес страницы сайта
полученный текст страницы обрабатывается, удаляются теги
из полученного текста формируется ТЗ с данными
По названию ищется поставщик из вспомогательного справочника Справочники.Pr_Поставщики.НайтиПоНаименованию(, если нет - создается
на выходе ТЗ с данными
В коде используется вспомогательная функция ПолучитьМассивИзСтрокиСРазделителем
Конечно, перед тем как мы начали это делать - прошерстили интернет и нашли несколько решений , вот они:
******************************* FAQ **************************************
(1) Как организовать дозвон? (тонкости организации дозвона)
1. Во первых, надо вручную создать подключение в списке удаленного
доступа (win 2000 - пуск, настройка, сеть и уд.доступ, создание
нового подключения).
Или создать подключение с помощью компоненты (см. "Атрибуты
подключений" и "СохранитьНастройкиПодключения()").
2. Если импульсный набор, то перед номером телефона надо ставить "p"
напр "p212121", тоновый - по умолчанию или "t". Если необходимо ждать
гудка после цифры, то ставится "w", напр. "t8w0952223333".
3. (только если RAS-сервер находится под управлением Windows 95-98)
Если система-клиент NT, 2000 или XP тогда в свойствах созданного
в п.1 соединения в разделе "Безопасность" выберите возможность
отправления незашифрованного пароля (win 2000 - закладка
"безопасность", п. Дополнительные (особые параметры), кн
"Настройка", п.Разрешить следующие протоколы, галочка
ТОЛЬКО на "Незашифрованный пароль PAP")
4. При вызове дозвона, необходимо использовать имя созданного в
п.1 подключения в качестве первого параметра.
5. При использовании процедуры "ОбработкаВнешнегоСобытия" (последний
параметр = 1 в Дозвониться (RASDIAL), ПолучитьПисьмо,
ПолучитьВсеПисьма (POP3), ОтправитьПисьмо, ОтправитьВсеПисьма(SMTP)
форма подключения в обязательном порядке должна быть в "фокусе",
иначе события могут теряться. Вернее они не теряются, а начинают
(пытаются) обрабатываться в глобальном модуле.
*********************************************************************
(2) Через какие объекты добраться до общих методов ?
Если методы и свойства "общие" это значит, что у объектов POP3 и SMTP есть одинаково действующие
методы и свойства.
!!! Отметим при этом, что Получ.РабочийКаталог<>Отпр.РабочийКаталог !!!
"РабочийКаталог" - одинаковое свойство для объектов POP3 и SMTP
*********************************************************************
(3) Почему при дозвоне компонента 3 раза подряд генерирует
событие "Начало Аутенфикации"?.
Дозвон происходит через системную DLL'ку RasDial.
Все события, которые генерируются этой DLL'кой перенаправляются
компонентой DialMail в 1С (процедура ОбработкаВнешнегоСобытия(...))
Так что от компоненты в данном случае ничего не зависит.
Причина этого (можно предположить) лежит на уровне того сервера,
к которому идет подсоединение (кто мешает аутенфикацию
проводить 3 раза или 3-мя различными способами?).
*********************************************************************
(4) При дозвоне (отправке, приеме почты) у меня в форме перестают
генерироваться события в процедуре ОбработкаВнешнегоСобытия(...),
хотя дозвон (отправка, прием почты) продолжает свою работу.
Это глюк 1С. Проявляется иногда во время работы компоненты при
сворачивании окон программ,открытия новых окон программ, при
потере фокуса 1С-Предприятием. Лечится это следующим образом.
На самом деле все события, сгенерированные компонентой, не пропадают
если процедуру ОбработкаВнешнегоСобытия(...) разместить
в глобальном модуле. В этом случае нам нужна будет глобальная
переменная - контекст нашей формы. Все переменные, которые нам
понадобятся в процедуре ОбработкаВнешнегоСобытия(...), можно
сделать либо глобальными, либо разместить на нашей форме в виде
невидимых реквизитов.
КоличествоСобытий - реквизит, размещенный на нашей форме
========================================
*********************************************************************
(5) Можно ли использовать дозвон для разговоров по телефону?
Нет. Компонента не предназначена для простых звонков на
телефон. Только для установления "сетевого" соединения между
2-мя компьютерами (например, между клиентским компьютером и
компьютером провайдера).
*********************************************************************
(6) Хотелось бы использовать компоненту DialMail в проектах,
написанных на Visual Basic, Delphi и т.д.
Компонента 1С хоть и полностью COM объект, но интерфейс
особый, свой - 1С-ий. Чтобы работать с данной компонентой
из других средств разработки, надо полностью переписывать
компоненту. Мне это не нужно, да и нет времени.
Модули Synapse, на которых базируются почтовые клиенты компонеты, лежат
в http://www.ararat.cz/synapse/ , могу прислать примеры компоненты
и интерфейсный модуль RasUnit.pas (для облегченной работы с RAS API -
тоже кстати из инета). Могу оказать посильную помощь, если что-то с этими
исходниками будет неясно. Но полностью исходники выложу в свободное
распространение только когда не буду поддерживать компоненту.
*********************************************************************
(8) Почему при передаче/приеме почты возникает ошибка 10054?
10054 - "Connection reset by peer", т.е. "Соединение сброшено удаленной
системой"
Происходит в результате:
1. Выключения сокета на удаленной машине в
рез-те ресета или таймаута
2. Вызывается локальной машиной при обнаружении потери
соединения (например, если дозванивались по dial-up и соединение
разорвалось - свойственно плохим модемам и плохим тел. линиям)
3. Связано с неправильным использованием "потоков" при приеме/передаче
Например, последовательность
может вызвать именно эту ошибку.
Пояснение: Т.к. получение запущено в отдельном потоке (3-ий параметр=1),
команда отключения вызовет закрытие сокета. Поток, который принимает почту,
из-за закрытия сокета "внешним процессом" инициирует данную ошибку -
фактически причина №2.
*********************************************************************
(9) RasDial: Как задать импульсный/тоновый набор номера,
паузу для ожидания гудка, и т.п. ?
Начинаться номер телефона может с "p" или "t" - cоответственно импульсный
или тоновый набор номера, по умолчанию - тоновый набор номера.
"w" - пауза, дождемся гудка - "линия свободна", "," - пауза в не помню сколько
времени (1 сек?) Пример задания телефонного номера: p8w095,,1234567
В данном примере - 'p' - импульсный набор, после '8' пауза, дождемся гудка,
после '095' подождем 2 сек и продолжим набирать номер. Более подробную
информацию по данным управляющим символам можно найти на просторах интернета.
Параметры:
<ИмяПроцедуры> (обязательный) Тип: Строка. Имя процедуры, подключаемой в качестве обработчика ожидания.
<Интервал> (обязательный) Тип: Число. Интервал времени в секундах с точностью до 1/10 секунды, через который будет осуществляться вызов процедуры (положительное число).Если указано значение меньше 1, то значение третьего параметра должно быть равно Истина.
<Однократно> (необязательный) Тип: Булево. Признак однократного выполнения обработчика ожидания.
Истина - указанный обработчик ожидания будет выполнен один раз. Значение по умолчанию: Ложь
Описание: Подключает указанную процедуру в качестве обработчика ожидания. Процедура будет вызываться в период ожидания системы каждый раз по истечению указанного интервала времени.
Примечание:
Вызов обработчика ожидания продолжается пока форма не будет закрыта или пока не будет вызван метод формы ОтключитьОбработчикОжидания.
Подключает вызов указанной процедуры модуля управляемого приложения (модуля обычного приложения) или глобального общего модуля через определенный интервал времени. Вызов будет осуществляться только в "состоянии покоя", то есть в тот момент, когда программа не выполняет никаких действий. Вызов обработчика ожидания продолжается, пока система не завершит работу или пока не будет вызван метод глобального контекста ОтключитьОбработчикОжидания.
Для Формы
Параметры:
<ИмяПроцедуры> (обязательный) Тип: Строка. Имя процедуры, подключаемой в качестве обработчика ожидания.
<Интервал> (обязательный) Тип: Число. Интервал времени в секундах с точностью до 1/10 секунды, через который будет осуществляться вызов процедуры (положительное число). Если указано значение меньше 1, то значение третьего параметра должно быть равно Истина.
<Однократно> (необязательный) Тип: Булево. Признак однократного выполнения обработчика ожидания. 0Истина - указанный обработчик ожидания будет выполнен один раз. Значение по умолчанию: Ложь
Описание:
Подключает указанную процедуру в качестве обработчика ожидания. Процедура будет вызываться в период ожидания системы каждый раз по истечению указанного интервала времени.
Доступность:
Толстый клиент. Примечание:
Вызов обработчика ожидания продолжается пока форма не будет закрыта или пока не будет вызван метод формы ОтключитьОбработчикОжидания.
Пример:
Обработка ожидания в системе 1С:Предприятие, как следует из документации, предназначена для периодического выполнения процедуры глобального модуля с заданным интервалом времени. Код для запуска будет выглядеть следующим образом:
Где "ОбновитьСчетчик_" - имя процедуры глобального модуля, которая будет запускаться с периодичностью в 1 сек. (второй параметр, равный 1)
Но! Проблема в том, что запустить обработку ожидания можно только 1 раз. Повторный запуск приведет к отмене предыдущего. Другими словами, если Вы хотите сделать, к примеру, обработку-таймер для отсчета затраченного времени, то запустить можно только один таймер, т.к. запуск второго таймера приведет к остановке первого. А что делать если Вам надо запустить 2, 3 или больше таких таймеров одновременно? Или Вам надо еще при этом периодически сканировать состояние документов?
Выход есть! Обработку ожидания надо запустить в контексте формы, чтобы отделить этот поток от глобального контекста. И тогда станет возможным периодический запуск процедуры локального модуля, т.е. процедуры, расположенной в модуле формы Вашей обработки.
Код для запуска будет выглядеть следующим образом:
Где "ОбновитьСчетчик_" - имя процедуры локального модуля формы обработки, которая будет запускаться с периодичностью в 1 сек. (второй параметр, равный 1)
Таким образом, в каждой обработке можно запустить свою обработку ожидания, которая будет работать до тех пор, пока открыта форма.
В формах можно использовать ,
где ИмяПроцедуры - имя процедуры, которая запускается через ВремяЗапуска секунд
В самой процедуре нужно вставить для прекращения обработки ожидания (естественно, после выполнения нужных условий).
Источник lessons1c
:
Появилась необходимость выложить часть данных из 1С в открытый доступ большому числу пользователей.
Что бы не нарушать условий лицензирования и обеспечить безопасность данных, было принято решение развернуть новую базу на MySQL. Так как особо модерировать ее никто не хочет, пришлось сделать управление MySQL-ной БД из 1С, и начал с создания структуры БД. Итак: Создаем 2 справочника неирархических, один подчинен другому.
а. Таблицы
б. Колонки
Таблицы - реквизиты:
Автокод - Булево (Определяет необходимость нумеровать запись уникальным кодом, или отдать нумерование на откуп MySQL)
Таблицы - колонки:
ТипДанных - Число (в коде определим тип хранящихся данных по числу)
Длина - Число (длина хранящихся данных)
МожетБытьНоль - булево (может ли хранится пустое значение)
Связь - СсылкаНа таблицу (С которой есть связь все к одному)
Заполняем значениями справочники...
Теперь подключаемся:
Сначала удалим таблицы если они есть:
Теперь приступим к созданию таблиц БД:
И под закуску недостающие функции, использованные в основном тексте:
Предполагается что название таблиц идут с префиксом например: prefix_NameTable
Код для получения новостей с сайта buh.ru, используется RSS-канал http://www.buh.ru/rss/rss-2.0.jsp
Данный код для 7.7, при использовании в 8-ой версии нужно заменить СоздатьОбъект( на Новый COMОбъект(, остальное вроде так же.
Процедура глобального контекста Предупреждение() выводит на экран модальное окно предупреждения. Текст предупреждения передается первым параметром, вторым – таймаут, содержащий указание количества секунд, через которое окно самостоятельно закроется (если раньше его не закроет пользователь), третьим указывается заголовок окна.