Чтение данных с сайта в формате XML и загрузка в 1С При разработке веб проекта нам потребовалось получать с одного сайта данные в формате XML и загружать их в 1С.
Сайт выдает XML вида (Ссылка на этот xml в коде, внизу):
Код 1C v 8.3 This XML file does not appear to have any style information associated with it. The document tree is shown below.
< updates version= "1.0" generator= "SEOBudget" url= "http://seobudget.ru/updates/" >
< update id= "cy" name= "Обновление тИЦ Яндекса" >
< date id= "1823" index= "1419324939" timestamp= "1419324939" > 23.12 . 2014 11 : 55 : 39 MSK< / date>
< date id= "1792" index= "1415776885" timestamp= "1415776885" > 12.11 . 2014 10 : 21 : 25 MSK< / date>
< date id= "1760" index= "1412923802" timestamp= "1412924102" > 10.10 . 2014 10 : 55 : 02 MSK< / date>
< / update>
< update id= "serp" name= "Обновление поисковой выдачи Яндекса" >
< date id= "1872" index= "1424898000" timestamp= "1425604249" > 06.03 . 2015 04 : 10 : 49 MSK< / date>
< date id= "1871" index= "1423602000" timestamp= "1425586715" > 05.03 . 2015 23 : 18 : 35 MSK< / date>
< date id= "1868" index= "1423602000" timestamp= "1425402241" > 03.03 . 2015 20 : 04 : 01 MSK< / date>
< / update>
< update id= "yaca" name= "Обновление Яндекс.Каталога" >
< date id= "1875" index= "1425931200" timestamp= "1425973201" > 10.03 . 2015 10 : 40 : 01 MSK< / date>
< date id= "1874" index= "1425758400" timestamp= "1425886502" > 09.03 . 2015 10 : 35 : 02 MSK< / date>
< date id= "1873" index= "1425585600" timestamp= "1425628803" > 06.03 . 2015 11 : 00 : 03 MSK< / date>
< / update>
< update id= "pr" name= "Обновление Google PR" >
< date id= "1512" index= "1386353345" timestamp= "1386353345" > 06.12 . 2013 22 : 09 : 05 MSK< / date>
< date id= "1265" index= "1360130400" timestamp= "1360130400" > 06.02 . 2013 10 : 00 : 00 MSK< / date>
< date id= "1196" index= "1352376123" timestamp= "1352376123" > 08.11 . 2012 16 : 02 : 03 MSK< / date>
< / update>
< update id= "user" name= "Обновление ПФ в Яндексе" >
< date id= "1799" index= "1415950021" timestamp= "1416986821" > 26.11 . 2014 10 : 27 : 01 MSK< / date>
< date id= "1763" index= "1409237032" timestamp= "1413211432" > 13.10 . 2014 18 : 43 : 52 MSK< / date>
< date id= "1665" index= "1400617705" timestamp= "1401222505" > 28.05 . 2014 00 : 28 : 25 MSK< / date>
< / update>
< / updates> < br>
В результате была написана обработка загрузки данных с сайта в 1С, ее код:
Код 1C v 8.3 &НаСервере
Функция ЧтениеXMLВДерево(Путь)
Дерево = Новый ДеревоЗначений;
Дерево. Колонки. Добавить( "Имя" ) ;
Дерево. Колонки. Добавить( "Значение" ) ;
XMLФайл = Новый ЧтениеXML;
XMLФайл. ОткрытьФайл( Путь) ;
ПрочитатьXMLПоТегам( XMLФайл, Дерево. Строки) ;
XMLФайл. Закрыть( ) ;
ТекДанные = Неопределено ;
Для каждого СтрокаП из Дерево. Строки Цикл
Для каждого СтрокаВ из СтрокаП. Строки Цикл
Для каждого СтрокаТ из СтрокаВ. Строки Цикл
Если СтрокаТ. Значение = "cy" тогда
ТекДанные = Перечисления. Показатель. TiC;
ИначеЕсли СтрокаТ. Значение = "serp" тогда
ТекДанные = Перечисления. Показатель. SYa;
ИначеЕсли СтрокаТ. Значение = "yaca" тогда
ТекДанные = Перечисления. Показатель. CatYa;
ИначеЕсли СтрокаТ. Значение = "pr" тогда
ТекДанные = Перечисления. Показатель. RP;
ИначеЕсли СтрокаТ. Значение = "user" тогда
ТекДанные = Перечисления. Показатель. PFYa;
КонецЕсли ;
Для каждого СтрокаД из СтрокаТ. Строки Цикл
Если СтрокаД. Имя= "timestamp" Тогда
ДатаИзменения = МестноеВремя( '19700101 '+ СтрокаД. значение) ;
НовЗапись = РегистрыСведений. ТиЦиRP. СоздатьМенеджерЗаписи( ) ;
НовЗапись. Показатель = ТекДанные;
НовЗапись. Период = ДатаИзменения;
НовЗапись. Записать( ) ;
КонецЕсли ;
КонецЦикла ;
КонецЦикла ;
КонецЦикла ;
КонецЦикла ;
КонецФункции
&НаСервереБезКонтекста
Процедура ПрочитатьXMLПоТегам(XMLФайл, ТекущийНаборСтрок)
Пока XMLФайл. Прочитать( ) Цикл
Если XMLФайл. ТипУзла = ТипУзлаXML. НачалоЭлемента Тогда
НоваяСтрока = ТекущийНаборСтрок. Добавить( ) ;
НоваяСтрока. Имя = XMLФайл. Имя;
НоваяСтрока. Значение = "" ;
Пока XMLФайл. ПрочитатьАтрибут( ) Цикл
НоваяСтрокаАтрибут = НоваяСтрока. Строки. Добавить( ) ;
НоваяСтрокаАтрибут. Имя = XMLФайл. Имя;
НоваяСтрокаАтрибут. Значение = СокрЛП( XMLФайл. Значение) ;
КонецЦикла ;
ПрочитатьXMLПоТегам( XMLФайл, НоваяСтрока. Строки) ;
ИначеЕсли XMLФайл. ТипУзла = ТипУзлаXML. КонецЭлемента Тогда
Возврат ;
ИначеЕсли XMLФайл. ТипУзла = ТипУзлаXML. Текст Тогда
ТекущийНаборСтрок. Родитель. Значение = СокрЛП( XMLФайл. Значение) ;
Иначе
Сообщить( "Тип узла: " + XMLФайл. ТипУзла + " НЕ ОБРАБОТАН" , СтатусСообщения. Важное) ;
Конецесли ;
КонецЦикла ;
КонецПроцедуры
&НаКлиенте
Процедура СборXML(Команда)
ЧтениеXMLВДерево( "http://seobudget.ru/downloads/updates.xml" ) ;
КонецПроцедуры
Результат загруженный в регистр сведений:
Категория:
Работа с Интернет, Почтой (Mail), FTP Как мы писали парсер сайта с ценами для 1С Недавно, мой постоянный клиент решил проводить маркетинговые исследования по изменению цен на товары у конкурентов... и эти данные захотел использовать в 1С в связке с его прайс-листом + куча отчетов с графиками и процентным отклонением от цен основного конкурента
В результате этого, была написана обработка собирающая данные со страниц разных сайтов. Из целей конфиденциальности - сайты раскрывать не буду...
Вид обработки загрузки данных с сайта в 1С
Ниже код загрузки данных со страницы сайта , смысл такой :
в функция передается адрес страницы сайта полученный текст страницы обрабатывается, удаляются теги из полученного текста формируется ТЗ с данными По названию ищется поставщик из вспомогательного справочника Справочники.Pr_Поставщики.НайтиПоНаименованию(, если нет - создается на выходе ТЗ с данными Код 1C v 8.х Функция ПолучитьТаблицуДанных(Строка)
тзДанных = Новый ТаблицаЗначений;
Сервер = "site.ru" ;
Соединение = Новый HTTPСоединение( Сервер) ;
Заголовки = Новый Соответствие;
Заголовки. Вставить( "host" , Сервер) ;
ТекАдрес = СтрЗаменить( Строка. Наименование. УРЛСтраницы, "http://" , "" ) ;
ТекАдрес = СтрЗаменить( ТекАдрес, Сервер, "" ) ;
Запрос = Новый HTTPЗапрос( ТекАдрес, Заголовки) ;
Ответ = Соединение. Получить( Запрос) ;
Если Ответ. КодСостояния = 200 Тогда
Содержимое= Ответ. ПолучитьТелоКакСтроку( ) ;
НачалоБлока = "<table id=" + """ " + "table-price" + """ " + " cellspacing=" + """ " + "0" + """ " + " border=" + """ " + "1" + """ " + " bordercolor=" + """ " + "#dedede" + """ " + " class=" + """ " + "tablesorter" + """ " + " >" ;
КонецБлока = "</table>" ;
ТекстБлока = Сред( Содержимое, Найти( Содержимое, НачалоБлока) + СтрДлина( НачалоБлока) , Найти( Содержимое, КонецБлока) - Найти( Содержимое, НачалоБлока) - СтрДлина( НачалоБлока) ) ;
обрТекст = СтрЗаменить( ТекстБлока, "<tr>" , "" ) ;
обрТекст = СтрЗаменить( обрТекст, "</tr>" , Символы. ПС) ;
обрТекст = СтрЗаменить( обрТекст, " >" , ">" ) ;
обрТекст = СтрЗаменить( обрТекст, "</th> <th>" , " | " ) ;
обрТекст = СтрЗаменить( обрТекст, "</td> <td>" , " | " ) ;
обрТекст = СтрЗаменить( обрТекст, "</th> <th class=" + """ " + "sortable_header" + """ " + ">" , " | " ) ;
обрТекст = СтрЗаменить( обрТекст, "</th> <th >" , " | " ) ;
обрТекст = СтрЗаменить( обрТекст, "</th><th>" , " | " ) ;
обрТекст = СтрЗаменить( обрТекст, "</td><td>" , " | " ) ;
обрТекст = СтрЗаменить( обрТекст, " >" , ">" ) ;
RegExp = Новый COMОбъект( "VBScript.RegExp" ) ;
RegExp. IgnoreCase = Ложь ;
RegExp. Global = Истина ;
RegExp. MultiLine = Истина ;
RegExp. Pattern = "<[^>]*>" ;
обрТекст= RegExp. Replace( обрТекст, "" ) ;
Если СокрЛП( обрТекст) = "Ни одной позиции не найдено." Тогда
Сообщить( Строка( Строка. Наименование) + " = Ни одной позиции не найдено! Строка " + Строка. Наименование) ;
Возврат тзДанных;
КонецЕсли ;
Если Найти( обрТекст, "Страница не найдена" ) > 0 Тогда
Сообщить( Строка( ТекАдрес) + " = Страница не найдена, строка " + Строка. Наименование) ;
Возврат тзДанных;
КонецЕсли ;
Для н= 1 По СтрЧислоСтрок( обрТекст) Цикл
СтрТекста= СтрПолучитьСтроку( обрТекст, н) ;
Если Найти( СтрТекста, "Длина Цена" ) > 0 Тогда
СтрТекста = СтрЗаменить( СтрТекста, "Длина Цена" , "Длина | Цена" ) ;
КонецЕсли ;
Если Найти( СтрТекста, "Марка стали Цена" ) > 0 Тогда
СтрТекста = СтрЗаменить( СтрТекста, "Марка стали Цена" , "Марка стали | Цена" ) ;
КонецЕсли ;
Если Найти( СтрТекста, ", Поставщик" ) > 0 Тогда
СтрТекста = СтрЗаменить( СтрТекста, ", Поставщик" , " | Поставщик" ) ;
КонецЕсли ;
мсДанных = ПолучитьМассивИзСтрокиСРазделителем( СтрТекста, "|" , Истина ) ;
Если н= 1 Тогда
Для Каждого ткЗнач из мсДанных Цикл
СтрЗапрещСимволов = " .,<>"" \/-" ;
ИмяКолонки = ткЗнач;
Для сч33 = 1 по СтрДлина( СтрЗапрещСимволов) Цикл
ЗапрещСимв = Сред( СтрЗапрещСимволов, сч33 , 1 ) ;
ИмяКолонки = СтрЗаменить( ИмяКолонки, ЗапрещСимв, "_" ) ;
КонецЦикла ;
Если НРег( ИмяКолонки) = "поставщик" Тогда
Для Сч_дк = ( Строка. Наименование. Родитель. Поставшик - 2 ) по тзДанных. Колонки. Количество( ) Цикл
тзДанных. Колонки. Добавить( "Колонка_" + ( тзДанных. Колонки. Количество( ) + 1 ) ) ;
КонецЦикла ;
КонецЕсли ;
тзДанных. Колонки. Добавить( ИмяКолонки) ;
КонецЦикла ;
тзДанных. Колонки. Добавить( "ном" , , , 7 ) ;
Иначе
НовСтр = тзДанных. Добавить( ) ; нмас= 0 ;
Для Каждого ткЗнач из мсДанных Цикл
НовСтр[нмас] = ткЗнач;
нмас= нмас+ 1 ;
КонецЦикла ;
НовСтр. ном = н;
КонецЕсли ;
КонецЦикла ;
тзДанных. Колонки. Добавить( "ЕстьСоответствие" , Новый ОписаниеТипов( "Булево" ) ) ;
тзДанных. Колонки. Добавить( "СпрPr_Поставщики" , Новый ОписаниеТипов( "СправочникСсылка.Pr_Поставщики" ) ) ;
Для каждого стр из тзДанных Цикл
текПоставщик = Справочники. Pr_Поставщики. НайтиПоНаименованию( стр[Строка. Наименование. родитель. Поставшик- 1 ]) ;
Если текПоставщик = Справочники. Pr_Поставщики. ПустаяСсылка( ) Тогда
НовЭлем = Справочники. Pr_Поставщики. СоздатьЭлемент( ) ;
НовЭлем. Наименование = СокрЛП( стр[Строка. Наименование. родитель. Поставшик- 1 ]) ;
НовЭлем. Записать( ) ;
текПоставщик = НовЭлем. Ссылка;
КонецЕсли ;
стр. СпрPr_Поставщики = текПоставщик;
КонецЦикла ;
Иначе
тзДанных. Колонки. Добавить( "ЕстьСоответствие" , Новый ОписаниеТипов( "Булево" ) ) ;
тзДанных. Колонки. Добавить( "СпрPr_Поставщики" , Новый ОписаниеТипов( "СправочникСсылка.Pr_Поставщики" ) ) ;
Сообщить( "Ошибка получения данных для строки " + Строка. Наименование) ;
КонецЕсли ;
Возврат тзДанных;
КонецФункции
В коде используется вспомогательная функция ПолучитьМассивИзСтрокиСРазделителем
Код 1C v 8.2 УП
Функция ПолучитьМассивИзСтрокиСРазделителем(Знач Стр, Разделитель = "." , ОбрезатьНепечатныеСимволы = Ложь) Экспорт
МассивСтрок = Новый Массив;
Если Разделитель = " " Тогда
Стр = СокрЛП( Стр) ;
Пока 1 = 1 Цикл
Поз = Найти( Стр, Разделитель) ;
Если Поз= 0 Тогда
МассивСтрок. Добавить( Стр) ;
Возврат МассивСтрок;
КонецЕсли ;
МассивСтрок. Добавить( Лев( Стр, Поз- 1 ) ) ;
Стр = СокрЛ( Сред( Стр, Поз) ) ;
КонецЦикла ;
Иначе
ДлинаРазделителя = СтрДлина( Разделитель) ;
Пока 1 = 1 Цикл
Поз = Найти( Стр, Разделитель) ;
Если Поз= 0 Тогда
Фрагмент = Стр;
Если ОбрезатьНепечатныеСимволы Тогда
Фрагмент = СокрЛП( Фрагмент) ;
КонецЕсли ;
МассивСтрок. Добавить( Фрагмент) ;
Возврат МассивСтрок;
КонецЕсли ;
Фрагмент = Лев( Стр, Поз- 1 ) ;
Если ОбрезатьНепечатныеСимволы Тогда
Фрагмент = СокрЛП( Фрагмент) ;
КонецЕсли ;
МассивСтрок. Добавить( Фрагмент) ;
Стр = Сред( Стр, Поз+ ДлинаРазделителя) ;
КонецЦикла ;
КонецЕсли ;
Возврат МассивСтрок;
КонецФункции
Конечно, перед тем как мы начали это делать - прошерстили интернет и нашли несколько решений , вот они:
Код 1C v 8.х Соединение = ПолучитьCOMОбъект( "" , "Microsoft.XMLHTTP" ) ;
ИмяВременногоФайла= ПолучитьИмяВременногоФайла( "htm" ) ;
Соединение. open( "GET" , "http://mamba.ru/my" , 0 ) ;
Соединение. send( ) ;
ТаймАут = 200 ;
Начало= ТекущаяДата( ) ;
Пока Соединение. readyState < > 4 И ( ТаймАут= 0 ИЛИ ТекущаяДата( ) - Начало< ТаймАут) Цикл
бфДиалоги. ксОбработкаПрерыванияПользователя( ) ;
КонецЦикла ;
обСохранитьДвоичныйБуферВФайл( Соединение. responseBody, ИмяВременногоФайла) ;
Соединение. open( "POST" , "http://mamba.ru/my" ) ;
Соединение. send( "login=xxx&password=&&&" ) ;
Функция обСохранитьДвоичныйБуферВФайл(Буфер, ИмяФайла) Экспорт
Поток = Новый COMОбъект( "ADODB.Stream" ) ;
Поток. Type = 1 ;
Поток. Mode = 3 ;
Поток. Open( ) ;
Поток. Write( Буфер) ;
Поток. SaveToFile( ИмяФайла) ;
Поток. Close( ) ;
КонецФункции
Код 1C v 8.х НТТР = ПолучитьCOMОбъект( "" , "Microsoft.XMLHTTP" ) ;
ИмяФайлаОтвета = КаталогВременныхФайлов( ) + "filename.tmp" ;
НТТР. open( "GET" , "www.google.com" , 0 , , ) ;
НТТР. send( ) ;
StreamTypeEnum = Новый Структура( "adTypeBinary, adTypeText" , 1 , 2 ) ;
ConnectModeEnum = Новый Структура(
"adModeRead, adModeReadWrite, adModeRecursive, adModeShareDenyNone,
|adModeShareDenyRead, adModeShareDenyWrite, adModeShareExclusive,
|adModeUnknown, adModeWrite" , 1 , 3 , 4194304 , 16 , 4 , 8 , 12 , 0 , 2 ) ;
SaveOptionsEnum = Новый Структура( "adSaveCreateNotExist, adSaveCreateOverWrite" , 1 , 2 ) ;
StreamOut = Новый COMОбъект( "ADODB.Stream" ) ;
StreamOut. Type = StreamTypeEnum. adTypeBinary;
StreamOut. Mode = ConnectModeEnum. adModeReadWrite;
StreamOut. Open( ) ;
StreamOut. Write( НТТР. responseBody) ;
StreamOut. SaveToFile( ИмяФайлаОтвета, SaveOptionsEnum. adSaveCreateOverWrite) ;
StreamOut. Close( ) ;
И даже не этом сайте есть статья : Парсер сайта связного на 1С
Нужен парсер сайта в 1С!? - Обращайтесь, контакты в
профиле Категория:
Работа с Интернет, Почтой (Mail), FTP Как обработать файлы с разделителями, изменив их структуру и сохранив в кодировке UTF8 без BOM Частенько при разработке сайтов приходится обрабатывать тысячи однотипных файлов... чтобы оптимизировать эту рутинную работу я набросал небольшую обработку, которая перебирает в указанном каталоге все файлы с расширением w1c и полностью меняет структуру данного файла, сохраняя его в кодировке UTF8 без BOM сигнатуры
Код обработки файлов:
Код 1C v 8.3 &НаКлиенте
Процедура КомандаОбрW1C(Команда)
Режим = РежимДиалогаВыбораФайла. ВыборКаталога;
ДиалогОткрытия = Новый ДиалогВыбораФайла( Режим) ;
ДиалогОткрытия. Каталог = "" ;
ДиалогОткрытия. МножественныйВыбор = Ложь ;
ДиалогОткрытия. Заголовок = "Выберите каталог с Файлами" ;
Если ДиалогОткрытия. Выбрать( ) Тогда
ПутьККаталогу = ДиалогОткрытия. Каталог;
ВыбранКаталог = НайтиФайлы( ПутьККаталогу, "*.*" ) ;
Для каждого НайденныйФайл Из ВыбранКаталог Цикл
Если НайденныйФайл. ЭтоКаталог( ) Тогда
ИначеЕсли НайденныйФайл. Расширение= ".w1c" Тогда
Сообщить( НайденныйФайл. ПолноеИмя) ;
ОбработатьФайл( НайденныйФайл. ПолноеИмя) ;
КонецЕсли ;
КонецЦикла ;
КонецЕсли ;
КонецПроцедуры
&НаКлиенте
Процедура ОбработатьФайл(ТекФайл)
ОбрФайл = Новый ТекстовыйДокумент;
ОбрФайл. Прочитать( ТекФайл, "UTF-8" ) ;
врТекст = ОбрФайл. ПолучитьТекст( ) ;
врМассив = РазложитьСтрокуВМассив( врТекст, "<&w1c&>" ) ;
новТекст = СокрЛП( врМассив[0 ]) + "<&w1c&>" ;
новТекст = новТекст + СокрЛП( врМассив[1 ]) + "<&w1c&>" + "1<&w1c&>" ;
АтрибутыФайла = Новый Файл( ТекФайл) ;
новТекст = новТекст + Формат( АтрибутыФайла. ПолучитьВремяИзменения( ) , "ДФ=dd/MM/yyyy" ) + "<&w1c&>" ;
новТекст = новТекст + СокрЛП( врМассив[2 ]) + "<&w1c&>" ;
новТекст = новТекст + СокрЛП( врМассив[3 ]) + "<&w1c&>" ;
новТекст = новТекст + СокрЛП( врМассив[4 ]) + "<&w1c&>" ;
новТекст = новТекст + СокрЛП( врМассив[5 ]) + "<&w1c&>" ;
новТекст = новТекст + "no-mods<&w1c&>" ;
новТекст = новТекст + СокрЛП( врМассив[6 ]) + "<&w1c&>" ;
новТекст = новТекст + СокрЛП( врМассив[7 ]) ;
ОбрФайл. Очистить( ) ;
ОбрФайл. УстановитьТекст( новТекст) ;
ОбрФайл. Записать( ТекФайл, "UTF-8" ) ;
Данные = Новый ДвоичныеДанные( ТекФайл) ;
Строка64 = Base64Строка( Данные) ;
Строка64 = Прав( Строка64 , СтрДлина( Строка64 ) - 4 ) ;
ДанныеНаЗапись= Base64Значение( Строка64 ) ;
ДанныеНаЗапись. Записать( ТекФайл) ;
КонецПроцедуры
&НаКлиенте
Функция РазложитьСтрокуВМассив(Знач Стр, Разделитель = "," ) Экспорт
МассивСтрок = Новый Массив( ) ;
Если Разделитель = " " Тогда
Стр = СокрЛП( Стр) ;
Пока 1 = 1 Цикл
Поз = Найти( Стр, Разделитель) ;
Если Поз= 0 Тогда
МассивСтрок. Добавить( Стр) ;
Возврат МассивСтрок;
КонецЕсли ;
МассивСтрок. Добавить( Лев( Стр, Поз- 1 ) ) ;
Стр = СокрЛ( Сред( Стр, Поз) ) ;
КонецЦикла ;
Иначе
ДлинаРазделителя = СтрДлина( Разделитель) ;
Пока 1 = 1 Цикл
Поз = Найти( Стр, Разделитель) ;
Если Поз= 0 Тогда
МассивСтрок. Добавить( Стр) ;
Возврат МассивСтрок;
КонецЕсли ;
МассивСтрок. Добавить( Лев( Стр, Поз- 1 ) ) ;
Стр = Сред( Стр, Поз+ ДлинаРазделителя) ;
КонецЦикла ;
КонецЕсли ;
КонецФункции
Внешний вид обработки получился таким:
Обработка написана для Web-Студии W1C : Первый Веб-Консультант
Категория:
Текстовый документ Подсчет реального количества месяцев между датами, включая начало и конец месяца В одном проекте понадобилось подсчитывать полное количество месяцев между датами,
Допустим надо получить кол-во месяцев между датами 25.10.14 и 21.11.14
Функция РазницаДатВМесяцах ( Как вычислить разницу между двумя датами в месяцах ) вернет 1 , по сути разница между датами = одному месяцу,
но по факту работы будут в 10 и 11 месяцах, т.е. всего 2, в итоге была написана простая функция, ее код ниже:
Код 1C v 8.2 УП тДат= ДатаНачала; КолМес = 0 ;
Пока Месяц( тДат) < > Месяц( ДатаОкончания) Цикл
КолМес = КолМес+ 1 ;
тДат = ДобавитьМесяц( тДат, 1 ) ;
КонецЦикла ;
Результат = КолМес+ 1 ;
Категория:
Работа с Датами (Временем) Загрузка картинок в базу 1С (сохранение в хранилище значений) В теме форма: v8: Получение данных из ХралищаЗначений
Bell в управляемом интерфейсе пробует сохранить выбранные картинки в базу 1С, но возникли сложности с сохранением в хранилище значений. как пример Bell приложил CF файл с мини конфигурацией, за что ему большое спасибо, т.к. большая часть материалов этой статьи написана им, я лишь поправил небольшие участки кода связанные с передачей файлов и сохранение в хранилище значений.
Так как везде уже Такси, то CF я перевел в этот режим и в нем демонстрирую.
Имеется справочник Хранилище данных :
Основная Форма Элемента:
Ее код:
Код 1C v 8.3
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Объект. Ссылка. Пустая( ) Тогда
Объект. Наименование = "." ;
КонецЕсли ;
Если НЕ Параметры. Ключ. Пустая( ) Тогда
ДанныеАдрес = ПолучитьНавигационнуюСсылку( Объект. Ссылка, "ДанныеХЗ" ) ;
КонецЕсли ;
КонецПроцедуры
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Если Объект. Ссылка. Пустая( ) Тогда
КонецЕсли ;
КонецПроцедуры
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
Если ЭтоАдресВременногоХранилища( ДанныеАдрес) Тогда
РежимСжатия = Новый СжатиеДанных( 9 ) ;
ДанныеСохранения = ПолучитьИзВременногоХранилища( ДанныеАдрес) ;
ТекущийОбъект. ДанныеХЗ = Новый ХранилищеЗначения( ДанныеСохранения, РежимСжатия) ;
КонецЕсли ;
КонецПроцедуры
&НаСервере
Процедура ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
Если ЭтоАдресВременногоХранилища( ДанныеАдрес) Тогда
УдалитьИзВременногоХранилища( ДанныеАдрес) ;
ДанныеАдрес = ПолучитьНавигационнуюСсылку( ТекущийОбъект. Ссылка, "ДанныеХЗ" ) ;
КонецЕсли ;
КонецПроцедуры
&НаКлиенте
Процедура ВыбратьДанные(Команда)
ДанныеВыбрать( ) ;
КонецПроцедуры
&НаКлиенте
Процедура СохранитьДанные(Команда)
Если НЕ ЗначениеЗаполнено( Объект. Ссылка) Тогда
Предупреждение( НСтр( "ru = 'Элемент не записан !!!'" ) ) ;
Возврат ;
КонецЕсли ;
ДанныеСохранения = ПолучитьНавигационнуюСсылку( Объект. Ссылка, "ДанныеХЗ" ) ;
ИмяСохранения = Объект. Наименование;
ПолучитьФайл( ДанныеСохранения, ИмяСохранения, Истина ) ;
КонецПроцедуры
&НаКлиенте
Процедура ДанныеВыбрать()
ПолученныеДанныеАдрес = "" ;
Если ПоместитьФайл( ПолученныеДанныеАдрес, , Объект. ДанныеПуть, Истина , УникальныйИдентификатор) Тогда
ДанныеАдрес = ПолученныеДанныеАдрес;
ВыбранныйФайл = Новый Файл( Объект. ДанныеПуть) ;
Объект. Наименование = ВыбранныйФайл. Имя;
Объект. ДанныеТекущаяДата = ТекущаяДата( ) ;
Модифицированность = Истина ;
КонецЕсли ;
КонецПроцедуры
так же имеется общая форма ФормаЗагрузкиФайлов
При помощи ее выбираются файлы изображений и загружаются в справочник - одновременно можно загружать несколько файлов
код формы:
Код 1C v 8.3
&НаКлиенте
Процедура СписокФайловПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа)
Отказ = Истина ;
ДобавитьФайлы( ) ;
КонецПроцедуры
&НаКлиенте
Процедура ДобавитьФайлы()
ВыборФайла = Новый ДиалогВыбораФайла( РежимДиалогаВыбораФайла. Открытие) ;
ВыборФайла. МножественныйВыбор = Истина ;
ВыборФайла. Заголовок = НСтр( "ru = 'Выбор файла'" , "ru" ) ;
ВыборФайла. Фильтр = НСтр( "ru = 'Все файлы'" , "ru" ) + " (*.*)|*.*" ;
ВыборФайла. ПредварительныйПросмотр = Истина ;
Если ВыборФайла. Выбрать( ) Тогда
Для каждого СтрокаФайл Из ВыборФайла. ВыбранныеФайлы Цикл
ОписаниеФайла = Новый Файл( СтрокаФайл) ;
НВС = СписокФайлов. Добавить( ) ;
НВС. ПолноеИмяФайла = СтрокаФайл;
НВС. РазмерФайла = ОписаниеФайла. Размер( ) ;
КонецЦикла ;
КонецЕсли ;
КонецПроцедуры
&НаКлиенте
Процедура Загрузить()
Если НЕ ПроверитьЗаполнение( ) Тогда
Возврат ;
КонецЕсли ;
ОчиститьСообщения( ) ;
Если СписокФайлов. Количество( ) = 0 Тогда
Сообщить( "Файлы не выбраны !!!'" ) ;
Возврат ;
КонецЕсли ;
ПомещаемыеФайлы = Новый Массив;
Для каждого СтрокаФайл Из СписокФайлов Цикл
Описание = Новый ОписаниеПередаваемогоФайла( СтрокаФайл. ПолноеИмяФайла, "" ) ;
ПомещаемыеФайлы. Добавить( Описание) ;
КонецЦикла ;
ПомещенныеФайлы = Новый Массив;
СписокЗагруженныхФайлов = Новый СписокЗначений;
Если ПоместитьФайлы( ПомещаемыеФайлы, ПомещенныеФайлы, , Ложь , УникальныйИдентификатор) Тогда
Закрыть( Истина ) ;
Иначе
Сообщение = Новый СообщениеПользователю( ) ;
Сообщение. Текст = НСтр( "ru = 'Файлы не загружены'" , "ru" ) ;
Сообщение. Сообщить( ) ;
КонецЕсли ;
ОповеститьОВыборе( ПомещенныеФайлы) ;
КонецПроцедуры
&НаСервере
Функция ПоместитьВыбранныеФайлыВХранилище(ПомещаемыеФайлы)
АдресХЗ = ПоместитьВоВременноеХранилище( ПомещаемыеФайлы, УникальныйИдентификатор) ;
Возврат АдресХЗ;
КонецФункции
в коде вызывается ОповеститьОВыборе(ПомещенныеФайлы) и срабатывает обработчик в ФормаСпискаДополнительно
Код 1C v 8.3 &НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
Если ИсточникВыбора. ИмяФормы = "ОбщаяФорма.ФормаЗагрузкиФайлов" Тогда
ОбработкаВыбораПодборНаСервере( ВыбранноеЗначение) ;
КонецЕсли ;
КонецПроцедуры
и следующим кодом идет создание элементов справочника и загрузка изображений из временного хранилища
Код 1C v 8.3 &НаСервере
Процедура ОбработкаВыбораПодборНаСервере(ВыбранноеЗначение)
Для Каждого СтрокаФайл Из ВыбранноеЗначение Цикл
Файл = Новый Файл( СтрокаФайл. Имя) ;
ХранимыйФайл = Справочники. ХранилищеДанныхСправочники. СоздатьЭлемент( ) ;
ХранимыйФайл. Наименование = Файл. Имя;
ХранимыйФайл. ДанныеПуть = Файл. Путь;
ХранимыйФайл. ДанныеТекущаяДата = ТекущаяДата( ) ;
ХранимыйФайл. ДанныеХЗ = Новый ХранилищеЗначения( ПолучитьИзВременногоХранилища( СтрокаФайл. Хранение) , Новый СжатиеДанных( ) ) ;
ХранимыйФайл. Записать( ) ;
КонецЦикла ;
Элементы. Список. Обновить( ) ;
КонецПроцедуры
Скачать DT - Платформа 8.3.4
Категория:
Работа с Хранилищем Значений Набор функций для работы с разделителями в строке Код 1C v 8.х
Функция ПолучитьМассивИзСтрокиСРазделителем(Знач Стр, Разделитель = "." , ОбрезатьНепечатныеСимволы = Ложь) Экспорт
МассивСтрок = Новый Массив;
Если Разделитель = " " Тогда
Стр = СокрЛП( Стр) ;
Пока 1 = 1 Цикл
Поз = Найти( Стр, Разделитель) ;
Если Поз= 0 Тогда
МассивСтрок. Добавить( Стр) ;
Возврат МассивСтрок;
КонецЕсли ;
МассивСтрок. Добавить( Лев( Стр, Поз- 1 ) ) ;
Стр = СокрЛ( Сред( Стр, Поз) ) ;
КонецЦикла ;
Иначе
ДлинаРазделителя = СтрДлина( Разделитель) ;
Пока 1 = 1 Цикл
Поз = Найти( Стр, Разделитель) ;
Если Поз= 0 Тогда
Фрагмент = Стр;
Если ОбрезатьНепечатныеСимволы Тогда
Фрагмент = СокрЛП( Фрагмент) ;
КонецЕсли ;
МассивСтрок. Добавить( Фрагмент) ;
Возврат МассивСтрок;
КонецЕсли ;
Фрагмент = Лев( Стр, Поз- 1 ) ;
Если ОбрезатьНепечатныеСимволы Тогда
Фрагмент = СокрЛП( Фрагмент) ;
КонецЕсли ;
МассивСтрок. Добавить( Фрагмент) ;
Стр = Сред( Стр, Поз+ ДлинаРазделителя) ;
КонецЦикла ;
КонецЕсли ;
Возврат МассивСтрок;
КонецФункции
Функция ПолучитьСтрокуСРазделителемИзМассива(пМассив, пРазделитель = ", " ) Экспорт
Результат = "" ;
Для Каждого Элемент Из пМассив Цикл
Результат = Результат + пРазделитель + Строка( Элемент) ;
КонецЦикла ;
Возврат Сред( Результат, СтрДлина( пРазделитель) + 1 ) ;
КонецФункции
Функция ПолучитьПервыйФрагмент(пСтрока, пРазделитель = "." ,
пЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина) Экспорт
Позиция = Найти( пСтрока, пРазделитель) ;
Если Позиция > 0 Тогда
Возврат Лев( пСтрока, Позиция - 1 ) ;
Иначе
Если пЛиИспользоватьГраницуЕслиМаркерНеНайден Тогда
Возврат пСтрока;
Иначе
Возврат пСтрока;
КонецЕсли ;
КонецЕсли ;
КонецФункции
Функция ПолучитьПоследнийФрагмент(пСтрока, пМаркер = "." ,
пЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина) Экспорт
Подстрока = пСтрока;
МаркерНайден = Ложь ;
Пока пМаркер < > "" Цикл
Позиция = Найти( Подстрока, пМаркер) ;
Если Позиция = 0 Тогда
Прервать ;
КонецЕсли ;
МаркерНайден = Истина ;
Подстрока = Сред( Подстрока, Позиция + СтрДлина( пМаркер) ) ;
КонецЦикла ;
Если Истина
И Не МаркерНайден
И пЛиИспользоватьГраницуЕслиМаркерНеНайден
Тогда
Возврат пСтрока;
ИначеЕсли МаркерНайден Тогда
Возврат Подстрока;
Иначе
Возврат "" ;
КонецЕсли ;
КонецФункции
Функция ПолучитьСтрокуМеждуМаркерами(пСтрока, пНачальныйМаркер = Неопределено, пКонечныйМаркер = Неопределено,
пЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина, пЛиВключатьМаркеры = Ложь) Экспорт
ПозицияНачальногоМаркера = Найти( пСтрока, пНачальныйМаркер) ;
Если Истина
И ПозицияНачальногоМаркера = 0
И пЛиИспользоватьГраницуЕслиМаркерНеНайден = Ложь
Тогда
Возврат Неопределено ;
КонецЕсли ;
Если Ложь
ИЛИ пНачальныйМаркер = Неопределено
ИЛИ ПозицияНачальногоМаркера = 0
Тогда
ПозицияНачальногоМаркера = - СтрДлина( пНачальныйМаркер) ;
КонецЕсли ;
Стр = Сред( пСтрока, ПозицияНачальногоМаркера + СтрДлина( пНачальныйМаркер) ) ;
ПозицияКонечногоМаркера = Найти( Стр, пКонечныйМаркер) ;
Если Истина
И ПозицияКонечногоМаркера = 0
И пЛиИспользоватьГраницуЕслиМаркерНеНайден = Ложь
Тогда
Возврат Неопределено ;
КонецЕсли ;
Если Ложь
ИЛИ пКонечныйМаркер = Неопределено
ИЛИ ПозицияКонечногоМаркера = 0
Тогда
ПозицияКонечногоМаркера = СтрДлина( Стр) + 1 ;
КонецЕсли ;
Результат = Лев( Стр, ПозицияКонечногоМаркера - 1 ) ;
Если пЛиВключатьМаркеры Тогда
Если пНачальныйМаркер < > Неопределено Тогда
Результат = пНачальныйМаркер + Результат;
КонецЕсли ;
Если пКонечныйМаркер < > Неопределено Тогда
Результат = Результат + пКонечныйМаркер;
КонецЕсли ;
КонецЕсли ;
Возврат Результат;
КонецФункции
Категория:
Работа с Текстом (Строкой) Поиск в базе битых ссылок - "объект не найден" В статье
Битая ссылка, <Объект не найден>, Уникальный Идентификатор, GUID мы обсуждали как востановить битые ссылки!
А вот как найти в базе все битые ссылки, которые имеют вид типа "<Объект не найден> (137:8b270030482898d011daad3cc45fc830)"?
Для поиска этого была
написана данная обработка:
Скачивать файлы может только зарегистрированный пользователь!
Для поиска: Выбираем объекты метаданных , которые хотим проверить, жмем кнопочку "Выполнить" и наблюдаем в таблице выходные данные. Откуда можем попасть в объекты-источники.
Для программиста:
Код 1C v 8.х Процедура КнопкаВыполнитьНажатие(Кнопка)
ИспользоватьОграничение = ЗначениеЗаполнено( ОграничениеТипов) ;
РезультатПоиска. Очистить( ) ;
Для Каждого ОбъектыМетаданных Из КоллекцияОбъектов Цикл
Для Каждого ОбъектМетаданных Из ОбъектыМетаданных Цикл
Состояние( ОбъектМетаданных. ПолноеИмя( ) ) ;
ПроверитьОбъектНаБитыеСсылки( ОбъектМетаданных) ;
КонецЦикла ;
КонецЦикла ;
Для Каждого ОбъектыМетаданных Из КоллекцияРегистров Цикл
Для Каждого ОбъектМетаданных Из ОбъектыМетаданных Цикл
Состояние( ОбъектМетаданных. ПолноеИмя( ) ) ;
ПроверитьРегистрНаБитыеСсылки( ОбъектМетаданных) ;
КонецЦикла ;
КонецЦикла ;
КонецПроцедуры
Процедура ВывестиДанные(ТекстЗапроса)
Запрос = Новый Запрос( ТекстЗапроса) ;
Попытка
РезультатЗапроса = Запрос. Выполнить( ) ;
Если Не РезультатЗапроса. Пустой( ) Тогда
ТЗ = РезультатЗапроса. Выгрузить( ) ;
Для Каждого Стр Из ТЗ Цикл
ОбработкаПрерыванияПользователя( ) ;
Строка = РезультатПоиска. Добавить( ) ;
ЗаполнитьЗначенияСвойств( Строка, Стр) ;
КонецЦикла ;
КонецЕсли ;
Исключение
Сообщить( ИнформацияОбОшибке( ) . Описание + " " + ИнформацияОбОшибке( ) . Причина) ;
КонецПопытки ;
КонецПроцедуры
Процедура ПроверитьРегистрНаБитыеСсылки(ОбъектМетаданных)
ИмяТаблицы = ОбъектМетаданных. ПолноеИмя( ) ;
Если Метаданные. РегистрыСведений. Содержит( ОбъектМетаданных) Тогда
Если ОбъектМетаданных. РежимЗаписи = НезависимыйРежимЗаписи Тогда
Возврат ;
КонецЕсли ;
АнализСвойствРегистра( ОбъектМетаданных, ОбъектМетаданных. Реквизиты, ИмяТаблицы) ;
КонецЕсли ;
АнализСвойствРегистра( ОбъектМетаданных, ОбъектМетаданных. Измерения, ИмяТаблицы) ;
АнализСвойствРегистра( ОбъектМетаданных, ОбъектМетаданных. Реквизиты, ИмяТаблицы) ;
АнализРегистратораРегистра( ОбъектМетаданных, ИмяТаблицы) ;
Если Метаданные. РегистрыБухгалтерии. Содержит( ОбъектМетаданных) Тогда
КонецЕсли ;
Если Метаданные. РегистрыРасчета. Содержит( ОбъектМетаданных) Тогда
КонецЕсли ;
КонецПроцедуры
Процедура ПроверитьОбъектНаБитыеСсылки(ОбъектМетаданных)
ИмяТаблицы = ОбъектМетаданных. ПолноеИмя( ) ;
АнализСвойствОбъекта( ОбъектМетаданных, ОбъектМетаданных. Реквизиты, ИмяТаблицы) ;
Для Каждого ТабЧасть Из ОбъектМетаданных. ТабличныеЧасти Цикл
Если ТабличныеЧастиИсключения. Найти( ТабЧасть. Имя) < > Неопределено Тогда
Продолжить;
КонецЕсли ;
АнализСвойствОбъекта( ОбъектМетаданных, ТабЧасть. Реквизиты, ИмяТаблицы + "." + ТабЧасть. Имя)
КонецЦикла ;
Если Метаданные. Справочники. Содержит( ОбъектМетаданных) И ОбъектМетаданных. Владельцы. Количество( ) > 0 Тогда
МассивВладельцев = Новый Массив;
Для Каждого Элемент Из ОбъектМетаданных. Владельцы Цикл
МассивВладельцев. Добавить( Элемент) ;
КонецЦикла ;
КонецЕсли ;
ОбработкаПрерыванияПользователя( ) ;
КонецПроцедуры
Процедура АнализСвойствОбъекта(ОбъектМетаданных, Свойства, ИмяТаблицы)
Для Каждого Реквизит Из Свойства Цикл
Если РеквизитыИсключения. Найти( Реквизит. Имя) < > Неопределено Тогда
Продолжить;
КонецЕсли ;
Для Каждого моТип Из Реквизит. Тип. Типы( ) Цикл
ТекстЗапроса = "" ;
МетаданныеТипа = Метаданные. НайтиПоТипу( моТип) ;
Если МетаданныеТипа < > Неопределено
И Не Метаданные. Перечисления. Содержит( МетаданныеТипа) Тогда
Если ИспользоватьОграничение Тогда
Если Не ПоискПоТипу( МетаданныеТипа. ПолноеИмя( ) ) Тогда
Продолжить;
КонецЕсли ;
КонецЕсли ;
ДобавитьВЗапросОбъект( ТекстЗапроса, ОбъектМетаданных, ИмяТаблицы, Реквизит. Имя, моТип) ;
КонецЕсли ;
Если Не ПустаяСтрока( ТекстЗапроса) Тогда
ВывестиДанные( ТекстЗапроса) ;
КонецЕсли ;
КонецЦикла ;
КонецЦикла ;
КонецПроцедуры
Процедура АнализСвойствРегистра(ОбъектМетаданных, Свойства, ИмяТаблицы)
Для Каждого Реквизит Из Свойства Цикл
Если РеквизитыИсключения. Найти( Реквизит. Имя) < > Неопределено Тогда
Продолжить;
КонецЕсли ;
Для Каждого моТип Из Реквизит. Тип. Типы( ) Цикл
ТекстЗапроса = "" ;
МетаданныеТипа = Метаданные. НайтиПоТипу( моТип) ;
Если МетаданныеТипа < > Неопределено
И Не Метаданные. Перечисления. Содержит( МетаданныеТипа) Тогда
Если ИспользоватьОграничение Тогда
Если Не ПоискПоТипу( МетаданныеТипа. ПолноеИмя( ) ) Тогда
Продолжить;
КонецЕсли ;
КонецЕсли ;
ДобавитьВЗапросРегистр( ТекстЗапроса, ОбъектМетаданных, ИмяТаблицы, Реквизит. Имя, моТип) ;
КонецЕсли ;
Если Не ПустаяСтрока( ТекстЗапроса) Тогда
ВывестиДанные( ТекстЗапроса) ;
КонецЕсли ;
КонецЦикла ;
КонецЦикла ;
КонецПроцедуры
Процедура АнализРегистратораРегистра(ОбъектМетаданных, ИмяТаблицы)
МассивРегистраторов = ПолучитьСписокРегистраторов( ОбъектМетаданных) ;
Для Каждого Регистратор Из МассивРегистраторов Цикл
Если РеквизитыИсключения. Найти( "Регистратор" ) < > Неопределено Тогда
Продолжить;
КонецЕсли ;
моТип = Регистратор;
ТекстЗапроса = "" ;
МетаданныеТипа = Метаданные. НайтиПоТипу( моТип) ;
Если МетаданныеТипа < > Неопределено
И Не Метаданные. Перечисления. Содержит( МетаданныеТипа) Тогда
Если ИспользоватьОграничение Тогда
Если Не ПоискПоТипу( МетаданныеТипа. ПолноеИмя( ) ) Тогда
Продолжить;
КонецЕсли ;
КонецЕсли ;
ДобавитьВЗапросРегистр( ТекстЗапроса, ОбъектМетаданных, ИмяТаблицы, "Регистратор" , моТип) ;
КонецЕсли ;
Если Не ПустаяСтрока( ТекстЗапроса) Тогда
ВывестиДанные( ТекстЗапроса) ;
КонецЕсли ;
КонецЦикла ;
КонецПроцедуры
Функция ПолучитьСписокРегистраторов(ОбъектМетаданных)
МассивРегистраторов = Новый Массив;
МенеджерОбъект = ПолучитьМенеджерОбъекта( ОбъектМетаданных) ;
Если МенеджерОбъект < > Неопределено Тогда
НаборЗаписей = МенеджерОбъект. СоздатьНаборЗаписей( ) ;
ЭлементОтбора = НаборЗаписей. Отбор. Регистратор;
МассивРегистраторов = ЭлементОтбора. ТипЗначения. Типы( ) ;
КонецЕсли ;
Возврат МассивРегистраторов;
КонецФункции
Функция ПолучитьМенеджерОбъекта(ОбъектМетаданных)
Перем МенеджерОбъекта;
Если Метаданные. РегистрыБухгалтерии. Содержит( ОбъектМетаданных) Тогда
МенеджерОбъекта = РегистрыБухгалтерии[ОбъектМетаданных. Имя];
ИначеЕсли Метаданные. РегистрыНакопления. Содержит( ОбъектМетаданных) Тогда
МенеджерОбъекта = РегистрыНакопления[ОбъектМетаданных. Имя];
ИначеЕсли Метаданные. РегистрыСведений. Содержит( ОбъектМетаданных) Тогда
МенеджерОбъекта = РегистрыСведений[ОбъектМетаданных. Имя];
ИначеЕсли Метаданные. РегистрыРасчета. Содержит( ОбъектМетаданных) Тогда
МенеджерОбъекта = РегистрыРасчета[ОбъектМетаданных. Имя];
КонецЕсли ;
Возврат МенеджерОбъекта;
КонецФункции
Функция ПоискПоТипу(ИмяТипа)
Результат = Ложь ;
Если ИспользоватьОграничение Тогда
МассивСтрок = ОграничениеТипов. НайтиСтроки( Новый Структура( "ТипДанных" , ИмяТипа) ) ;
Если ЗначениеЗаполнено( МассивСтрок) Тогда
Результат = Истина ;
КонецЕсли ;
КонецЕсли ;
Возврат Результат;
КонецФункции
Процедура ДобавитьВЗапросРегистр(ТекстЗапроса, ОбъектМетаданных, ИмяТаблицы, ИмяРеквизита, ТипРеквизита)
Текст = "ВЫБРАТЬ Об." + ИмяРеквизита + " КАК Объект,
| "" " + ИмяТаблицы + "." + ИмяРеквизита + """ КАК ТаблицаИсточник,
| Об.Регистратор КАК ОбъектИсточник,
| " + ДобавитьОписаниеТипа( ИмяРеквизита, ТипРеквизита) + "
|ИЗ
| " + ИмяТаблицы + " КАК Об
|ГДЕ " + ДобавитьУсловия( ИмяРеквизита, ТипРеквизита) ;
ТекстЗапроса = ТекстЗапроса + ? ( ПустаяСтрока( ТекстЗапроса) , "" , Символы. ПС + "ОБЪЕДИНИТЬ ВСЕ" + Символы. ПС) + Текст;
КонецПроцедуры
Процедура ДобавитьВЗапросОбъект(ТекстЗапроса, ОбъектМетаданных, ИмяТаблицы, ИмяРеквизита, ТипРеквизита)
Текст = "ВЫБРАТЬ Об." + ИмяРеквизита + " КАК Объект,
| "" " + ИмяТаблицы + "." + ИмяРеквизита + """ КАК ТаблицаИсточник,
| Об.Ссылка КАК ОбъектИсточник,
| " + ДобавитьОписаниеТипа( ИмяРеквизита, ТипРеквизита) + "
|ИЗ
| " + ИмяТаблицы + " КАК Об
|ГДЕ " + ДобавитьУсловия( ИмяРеквизита, ТипРеквизита) ;
ТекстЗапроса = ТекстЗапроса + ? ( ПустаяСтрока( ТекстЗапроса) , "" , Символы. ПС + "ОБЪЕДИНИТЬ ВСЕ" + Символы. ПС) + Текст;
КонецПроцедуры
Функция ДобавитьУсловия(ИмяРеквизита, ТипРеквизита)
мдОбъекта = Метаданные. НайтиПоТипу( ТипРеквизита) ;
ИмяТаблицы = мдОбъекта. ПолноеИмя( ) ;
ПроверкаНаПустыеЗначения = " Об." + ИмяРеквизита + " ССЫЛКА " + ИмяТаблицы;
ПроверкаНаПустыеЗначения = ПроверкаНаПустыеЗначения + " И ВЫРАЗИТЬ(Об." + ИмяРеквизита + " КАК " + ИмяТаблицы + ").Ссылка есть null" ;
Если Не Метаданные. Перечисления. Содержит( мдОбъекта) Тогда
ПроверкаНаПустыеЗначения = ПроверкаНаПустыеЗначения + " И Об." + ИмяРеквизита + " <> Значение(" + ИмяТаблицы + ".ПустаяСсылка)" ;
КонецЕсли ;
Возврат ПроверкаНаПустыеЗначения;
КонецФункции
Функция ДобавитьОписаниеТипа(ИмяРеквизита, ТипРеквизита)
ОбъектТипа = Метаданные. НайтиПоТипу( ТипРеквизита) ;
ИмяТаблицы = ОбъектТипа. ПолноеИмя( ) ;
ОписаниеТипа = """ " + ИмяТаблицы + """ КАК ТипДанных" ;
Возврат ОписаниеТипа;
КонецФункции
Процедура ОграничениеТиповТипДанныхНачалоВыбора(Элемент, СтандартнаяОбработка)
Перем ЭлементСписка;
СтандартнаяОбработка = Ложь ;
Строка = ЭлементыФормы. ОграничениеТипов. ТекущиеДанные;
Если Не ПустаяСтрока( Строка. ТипДанных) Тогда
ЭлементСписка = СписокТипов. НайтиПоЗначению( Строка. ТипДанных) ;
КонецЕсли ;
ВыбранныйЭлемент = СписокТипов. ВыбратьЭлемент( , ЭлементСписка) ;
Если ВыбранныйЭлемент < > Неопределено Тогда
Строка. ТипДанных = ВыбранныйЭлемент. Значение;
КонецЕсли ;
КонецПроцедуры
РеквизитыИсключения = Новый Массив;
ТабличныеЧастиИсключения = Новый Массив;
СписокТипов = Новый СписокЗначений;
Для Каждого ОбъектМетаданных Из Метаданные. Справочники Цикл
СписокТипов. Добавить( ОбъектМетаданных. ПолноеИмя( ) , ОбъектМетаданных. Имя, , БиблиотекаКартинок. СправочникОбъект) ;
КонецЦикла ;
Для Каждого ОбъектМетаданных Из Метаданные. Документы Цикл
СписокТипов. Добавить( ОбъектМетаданных. ПолноеИмя( ) , ОбъектМетаданных. Имя, , БиблиотекаКартинок. ДокументОбъект) ;
КонецЦикла ;
КоллекцияОбъектов = Новый Массив;
КоллекцияОбъектов. Добавить( Метаданные. ПланыОбмена) ;
КоллекцияОбъектов. Добавить( Метаданные. Справочники) ;
КоллекцияОбъектов. Добавить( Метаданные. Документы) ;
КоллекцияОбъектов. Добавить( Метаданные. ПланыВидовХарактеристик) ;
КоллекцияОбъектов. Добавить( Метаданные. ПланыСчетов) ;
КоллекцияОбъектов. Добавить( Метаданные. ПланыВидовРасчета) ;
КоллекцияОбъектов. Добавить( Метаданные. БизнесПроцессы) ;
КоллекцияОбъектов. Добавить( Метаданные. Задачи) ;
КоллекцияРегистров = Новый Массив;
КоллекцияРегистров. Добавить( Метаданные. РегистрыСведений) ;
КоллекцияРегистров. Добавить( Метаданные. РегистрыНакопления) ;
КоллекцияРегистров. Добавить( Метаданные. РегистрыБухгалтерии) ;
КоллекцияРегистров. Добавить( Метаданные. РегистрыРасчета) ;
Категория:
1С Общие вопросы - Обычные формы Отправка sms из 1C через avisosms.ru. Столкнулся с задачей отправки sms из 1С. Спасибо Якову за напутствие в решении данной задачи и указание сервиса avisosms.ru.
На сайте сервиса предоставлена документация по работе с ним. В частности сервис предлагает следующие варианты работы:
* JSON протокол
* email2SMS протокол
* HTTP GET протокол
* Удаленный доступ к телефонной книге
* XML протокол
После проб и ошибок с протоколом email2sms (ну не любит мой провайдер через smtp слать письма на не очень красивые адреса относя их к спаму и блокируя) был выбран вариант решения с JSON протоколом. Для краткой демонстрации работы сервера приведена небольшая конфигурация. Конфигурация
написана на 1С Предприятие 8.2 с поддержкой работы веб-клиента. Для работы конфигурации необходимо заполнить константы:
* ПользовательСМС – Ваш логин в систему;
* ПарольСМС – Ваш пароль в систему;
* ПодписьСМС – Ваш адрес отправителя, который был создан в личном кабинете.
Конфигурация позволяет:
* Отправлять смс контрагенту, номер которого записан в соответствующем реквизите (номер пишем в формате 380ХХХХХХХХХХ);
* Получать статусы отправленных смс.
Ниже приведу код формирования запроса на отправку смс
Код 1C v 8.2 УП &НаСервере
Функция ОтправитьСервер()
УспешнаяОтправка = Ложь ;
ПараметрJSON = "{'username': '" + Константы. ПользовательСМС. Получить( ) + "'" ;
ПараметрJSON = ПараметрJSON + ",'password': '" + Константы. ПарольСМС. Получить( ) + "'" ;
ПараметрJSON = ПараметрJSON + ",'request_type': 'send_message'" ;
ПараметрJSON = ПараметрJSON + ",'destination_address': '" + Объект. Контрагент. НомерТелефона+ "'" ;
ПараметрJSON = ПараметрJSON + ",'message': '" + Объект. ТекстСМС+ "'" ;
ПараметрJSON = ПараметрJSON + ",'source_address': '" + Константы. ПодписьСМС. Получить( ) + "'" ;
ПараметрJSON = ПараметрJSON + ",flash:'0'}" ;
Попытка
WinHttp= Новый COMОбъект( "WinHttp.WinHttpRequest.5.1" ) ;
WinHttp. Option( 2 , "Windows-1251" ) ;
WinHttp. Open( "POST" , "http://api.avisosms.ru/sms/json/" , 0 ) ;
WinHttp. SetRequestHeader( "Accept-Language" , "ru" ) ;
WinHttp. SetRequestHeader( "Accept-Charset" , "Windows-1251" ) ;
WinHttp. setRequestHeader( "Content-Language" , "ru" ) ;
WinHttp. setRequestHeader( "Content-Charset" , "Windows-1251" ) ;
WinHttp. setRequestHeader( "Content-Type" , "application/x-www-form-urlencoded; charset=Windows-1251" ) ;
WinHttp. Send( ПараметрJSON) ;
ТекстОтвет = WinHttp. ResponseText( ) ;
Если Найти( ТекстОтвет, "OK_Operation_Completed" ) Тогда
УспешнаяОтправка = Истина ;
КонецЕсли ;
Исключение
Сообщить( "Ошибка соединения:" ) ;
Сообщить( ОписаниеОшибки( ) ) ;
КонецПопытки ;
Если УспешнаяОтправка Тогда
ПозицияКодаНачало = Найти( ТекстОтвет, "messageId" ) + СтрДлина( "messageId" ) + 3 ;
ПозицияКодаКонец = Найти( ТекстОтвет, "}" ) ;
КодСМС = Сред( ТекстОтвет, ПозицияКодаНачало, ПозицияКодаКонец- ПозицияКодаНачало- 1 ) ;
СМСРассылка. ЗаписатьСМСВИсторию( Объект. Контрагент, Объект. ТекстСМС, КодСМС) ;
Иначе
Сообщить( "Отправка смс не состоялась. Текст ошибки: " + ТекстОтвет) ;
КонецЕсли ;
Возврат УспешнаяОтправка;
КонецФункции
Источник Категория:
COM-объекты, WMI, WSH Функция проверки, строка написана только русскими и латинскими буквами? Код 1C v 8.х
Функция СтрокаНаписанаРусскимиИлиЛатинскими(Знач СтрокаПараметр)
СтрокаПараметр = СокрЛП( СтрокаПараметр) ;
КоличествоСимволов = СтрДлина( СтрокаПараметр) ;
Если КоличествоСимволов > 0 Тогда
ПервыйСимвол = КодСимвола( Лев( СтрокаПараметр, 1 ) ) ;
Русские = ( ПервыйСимвол > = 192 ) или ( ПервыйСимвол = 184 ) или ( ПервыйСимвол = 168 ) ;
СписокДопустимыхЗначений = Новый Соответствие;
СписокДопустимыхЗначений. Вставить( 184 , Истина ) ;
СписокДопустимыхЗначений. Вставить( 168 , Истина ) ;
СписокДопустимыхЗначений. Вставить( 45 , Истина ) ;
Для Сч = 1 По КоличествоСимволов Цикл
Код = КодСимвола( Сред( СтрокаПараметр, Сч) ) ;
Если Русские Тогда
Если ( СписокДопустимыхЗначений[Код] = Неопределено ) и ( Код < 192 ) Тогда
Возврат Ложь ;
КонецЕсли ;
ИначеЕсли ( Код < > 45 ) и ( ( Код < 65 ) или ( Код > 90 ) и ( Код < 97 ) или ( Код > 122 ) ) Тогда
Возврат Ложь ;
КонецЕсли ;
КонецЦикла ;
Возврат Истина ;
Иначе
Возврат Истина ;
КонецЕсли ;
КонецФункции
Категория:
Работа с Текстом (Строкой) Функция проверки наличия только русских букв в строке допускаются пробелы и дефис и спецсимволы Код 1C v 8.х Функция СтрокаНаписанаПоРусски(Знач СтрокаПараметр) Экспорт
СтрокаПараметр = СокрЛП( СтрокаПараметр) ;
СписокДопустимыхЗначений = Новый СписокЗначений;
СписокДопустимыхЗначений. Добавить( 184 ) ;
СписокДопустимыхЗначений. Добавить( 168 ) ;
СписокДопустимыхЗначений. Добавить( 45 ) ;
СписокДопустимыхЗначений. Добавить( 46 ) ;
СписокДопустимыхЗначений. Добавить( 32 ) ;
СписокДопустимыхЗначений. Добавить( 48 ) ;
СписокДопустимыхЗначений. Добавить( 49 ) ;
СписокДопустимыхЗначений. Добавить( 50 ) ;
СписокДопустимыхЗначений. Добавить( 51 ) ;
СписокДопустимыхЗначений. Добавить( 52 ) ;
СписокДопустимыхЗначений. Добавить( 53 ) ;
СписокДопустимыхЗначений. Добавить( 54 ) ;
СписокДопустимыхЗначений. Добавить( 55 ) ;
СписокДопустимыхЗначений. Добавить( 56 ) ;
СписокДопустимыхЗначений. Добавить( 57 ) ;
Для Сч= 1 По СтрДлина( СтрокаПараметр) Цикл
Код = КодСимвола( СтрокаПараметр, Сч) ;
Если ( Код< 192 ) И ( СписокДопустимыхЗначений. НайтиПоЗначению( Код) = Неопределено ) Тогда
Возврат Ложь ;
КонецЕсли ;
КонецЦикла ;
Возврат Истина ;
КонецФункции
Категория:
Работа с Текстом (Строкой) Функция дни рождения сотрудников Данная функция
написана для ЗиК 7.7
Код 1C v 7.x
Функция СтрГода(Возраст)
Остаток = Возраст%10 ;
Если Остаток = 1 Тогда
Стр = "год" ;
ИначеЕсли ( ( Остаток > 1 ) и ( Остаток < 5 ) ) Тогда
Стр = "года" ;
Иначе
Стр = "лет" ;
КонецЕсли ;
Возврат Стр;
КонецФункции
Процедура ДниРожденияСотрудников()
ТекстДР= "" ;
Именинники = СоздатьОбъект( "СписокЗначений" ) ;
СпрСотр = СоздатьОбъект( "Справочник.Сотрудники" ) ;
СпрСотр. ВыбратьЭлементы( ) ;
Пока СпрСотр. ПолучитьЭлемент( ) = 1 Цикл
ТекЭлем = СпрСотр. ТекущийЭлемент( ) ;
Если ТекЭлем. ЭтоГруппа( ) = 0 Тогда
Если ( ( ТекЭлем. Родитель < > "Уволенные" ) ) Тогда
ТекСотр = СпрСотр. ТекущийЭлемент( ) ;
Если ( ПустоеЗначение( ТекСотр. СостояниеФизЛица. Получить( НачМесяца( ТекущаяДата( ) ) ) ) = 0 ) Тогда
Если ( ДатаМесяц( ТекСотр. ДатаРождения) = ДатаМесяц( ТекущаяДата( ) ) ) Тогда
Именинники. ДобавитьЗначение( ТекСотр) ;
КонецЕсли ;
КонецЕсли ;
КонецЕсли ;
КонецЕсли ;
КонецЦикла ;
Если Именинники. РазмерСписка( ) < > 0 Тогда
ТекстДР= ТекстДР+ " ********* СПИСОК ИМЕНИННИКОВ *********" + РазделительСтрок+ " за месяц " + Формат( ТекущаяДата( ) , "ДММММ" ) + РазделительСтрок;
ТекстДР= ТекстДР+ "-----------------------------------------------------------------------------------------------------------------------------------------------" + РазделительСтрок;
Для к = 1 по Именинники. РазмерСписка( ) Цикл
Сотр = Именинники. ПолучитьЗначение( к) ;
Возраст = ( Число( ДатаГод( ТекущаяДата( ) ) ) - Число( ДатаГод( Сотр. ДатаРождения) ) ) ;
РазницаДней = ( Число( ДатаЧисло( Сотр. ДатаРождения) ) - Число( ДатаЧисло( ТекущаяДата( ) ) ) ) ;
СтрГода = СтрГода( Возраст) ;
Если ( ДатаЧисло( Сотр. ДатаРождения) < ДатаЧисло( ТекущаяДата( ) ) ) Тогда
ТекстДР= ТекстДР+ " " + Сотр+ " " + Сотр. ДатаРождения+ " уже исполнилось " + Возраст+ " " + СтрГода+ "!" + РазделительСтрок;
Иначе
Если ( РазницаДней = 2 ) Тогда
ТекстДР= ТекстДР+ "ПОСЛЕЗАВТРА! " + Сотр+ " послезавтра " + Сотр. ДатаРождения+ " будет праздновать " + Возраст + "-й День Рождения!!!! " ;
ИначеЕсли ( РазницаДней = 1 ) Тогда
ТекстДР= ТекстДР+ "ЗАВТРА! " + Сотр + " будет отмечает свой " + Возраст + "-й День рождения!" ;
ИначеЕсли ( РазницаДней = 0 ) Тогда
ТекстДР= ТекстДР+ "СЕГОДНЯ! " + Сотр + " отмечает свой " + Возраст + "-й День рождения!" ;
КонецЕсли ;
ТекстДР= ТекстДР+ " ( " + Сотр. Подразделение. Получить( ТекущаяДата( ) ) + " , " + Сотр. Должность. Получить( ТекущаяДата( ) ) + " )" + РазделительСтрок;
КонецЕсли ;
КонецЦикла ;
Иначе
ТекстДР= ТекстДР+ "В текущем месяце именинников нет!" ;
КонецЕсли ;
Сообщить( ТекстДР) ;
КонецПроцедуры
В файловом архиве есть и сама обработка.
Категория:
Полезные, Универсальные Функции Как сохранить поле BLOB (image) как файл на диск? Наиболее эффективно это можно сделать с помощью объектов OLE Automation , работа с которыми осуществляется при помощи:
sp_OACreate, sp_OAGetProperty, sp_OASetProperty, sp_OAMethod, sp_OAGetErrorInfo, sp_OADestroy (подробное описание есть в http://technet.microsoft.com/ru-ru/library/ms203721(sql.90).aspx).
Рабочий пример процедуры (была
написана для сохранения zip-архивов, хранящихся в базе):
Код CREATE PROCEDURE dbo.SaveRequestDataAsFile (
@FileName varchar(1024) --имя файла
,@FilePath varchar(1024) --путь файла
,@ReqID --некое условие на таблицу
)
AS
BEGIN
DECLARE
@Stream integer,
@Buffer varbinary(4096),
@Size integer,
@Pos integer,
@BufSize integer,
@FileNameLocal varchar(1024),
@HR integer
if RIGHT(@FilePath, 1)<>'&# 092;' begin set @FilePath=@FilePath+'&# 092;' end
set @FileNameLocal = @FilePath + @FileName
SET @BufSize = 4096
EXEC @HR = sp_OACreate 'ADODB.Stream',@Stream OUT
if @HR<>0
begin
--обработка ошибки создания объекта
EXEC [dbo].[sp_displayoaerrorinfo] @Stream ,@HR
end
EXEC @HR = sp_OASetProperty @Stream,'Type',1 -- binary
EXEC @HR = sp_OASetProperty @Stream,'Mode',3 -- write|read
EXEC @HR = sp_OAMethod @Stream,'Open'
S_elect
@Size = DATALENGTH(SrvRequests.RequestData)
FROM SrvRequests WHERE SrvRequests.RequestID = @ReqID
Set @Pos=0
WHILE @Pos < @Size BEGIN
SET @BufSize = CASE WHEN @Size - @Pos < 4096 THEN @Size - @Pos ELSE 4096 END
S_elect @Buffer = substring(SrvRequests.RequestData ,@Pos+1, @BufSize)
from SrvRequests where SrvRequests.RequestID = @ReqID
EXEC @HR = sp_OAMethod @Stream, 'Write', NULL, @Buffer
SET @Pos = @Pos + @BufSize
END
EXEC @HR = sp_OAMethod @Stream,'SaveToFile',null, @FileNameLocal,2
EXEC @HR = sp_OAMethod @Stream,'Close'
EXEC @HR = sp_OADestroy @Stream
END
Рекомендуется создать еще пару процедур для внятного описания ошибок в случае их возникновения
Код CREATE PROCEDURE sp_hexadecimal
@binvalue varbinary(255),
@hexvalue varchar(255) OUTPUT
AS
DECLARE @charvalue varchar(255)
DECLARE @i int
DECLARE @length int
DECLARE @hexstring char(16)
S_elect @charvalue = '0x'
S_elect @i = 1
S_elect @length = DATALENGTH(@binvalue)
S_elect @hexstring = '0123456789abcdef'
WHILE (@i <= @length)
BEGIN
DECLARE @tempint int
DECLARE @firstint int
DECLARE @secondint int
S_elect @tempint = CONVERT(int, SUBSTRING(@binvalue,@i,1))
S_elect @firstint = FLOOR(@tempint/16)
S_elect @secondint = @tempint - (@firstint* 16)
S_elect @charvalue = @charvalue +
SUBSTRING(@hexstring, @firstint+1, 1) +
SUBSTRING(@hexstring, @secondint+1, 1)
S_elect @i = @i + 1
END
----------------------------------------------------------------------
CREATE PROCEDURE sp_displayoaerrorinfo
@object int,
@hresult int
AS
DECLARE @output varchar(255)
DECLARE @hrhex char(10)
DECLARE @hr int
DECLARE @source varchar(255)
DECLARE @description varchar(255)
PRINT 'OLE Automation Error Information'
EXEC sp_hexadecimal @hresult, @hrhex OUT
S_elect @output = ' HRESULT: ' + @hrhex
PRINT @output
EXEC @hr = sp_OAGetErrorInfo @object, @source OUT, @description OUT
IF @hr = 0
BEGIN
S_elect @output = ' Source: ' + @source
PRINT @output
S_elect @output = ' Description: ' + @description
PRINT @output
END
ELSE
BEGIN
PRINT ' sp_OAGetErrorInfo failed.'
RETURN
END
Категория:
OLE, ActiveX