Открыли документ Счет, в поле Контрагент набираете первую букву & поиск осуществляется, набираете вторую (третью) букву и список становится пустым - это слетел индекс полнотекстового поиска, его нужно обновить:
- Главное меню - Все функции - Стандартные - Управление полнотекстовым поиском
Если Пункт меню Все функции недоступен, то включить его можно в меню Сервис - Параметры - Показывать Все функции
или такой вариант:
Меню - Администрирование - Поддержка и обслуживание - Регламентные операции - Полнотекстовый поиск данных - Настроить - Очистить индекс - Обновить индекс
Недавно, мой постоянный клиент решил проводить маркетинговые исследования по изменению цен на товары у конкурентов... и эти данные захотел использовать в 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С!? - Обращайтесь, контакты в
профиле Считать данные из двоичного файла можно при помощи функции ДвоичныеДанные(ИмяФайла). Например:
Код 1C v 8.2 УП ДД = ДвоичныеДанные( ИмяФайла) ;
или через ADODB.Stream
Код 1C v 8.х Процедура Пример(ИмяФайла)
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 ) ;
StreamIn = Новый COMОбъект( "ADODB.Stream" ) ;
StreamIn. Type = StreamTypeEnum. adTypeBinary;
StreamIn. Open( ) ;
StreamIn. LoadFromFile( ИмяФайла) ;
Data = StreamIn. Read( ) ;
StreamIn. Close( ) ;
СодержимоеМассив = Data. Выгрузить( ) ;
Data = Новый COMSafeArray( СодержимоеМассив, "VT_UI1" , СодержимоеМассив. Количество( ) ) ;
StreamOut = Новый COMОбъект( "ADODB.Stream" ) ;
StreamOut. Type = StreamTypeEnum. adTypeBinary;
StreamOut. Mode = ConnectModeEnum. adModeReadWrite;
StreamOut. Open( ) ;
StreamOut. Write( Data) ;
StreamOut. SaveToFile( ИмяФайла, SaveOptionsEnum. adSaveCreateOverWrite) ;
StreamOut. Close( ) ;
КонецПроцедуры
Двоичные данные и кодировка Base64 в 1С 8.Х
Считать данные из двоичного файла можно при помощи функции
ДвоичныеДанные(ИмяФайла). Например:
Код 1C v 8.2 УП ДД = ДвоичныеДанные( ИмяФайла) ;
Здесть ДД - специальный объект, который называется "двоичные данные".
В языке 1С есть функция, которая преобразует двоичные данные в строку
Base64Строка(ДвоичныеДанные). Например:
Код 1C v 8.2 УП Строка64 = Base64Строка( ДвоичныеДанные) ;
Здесть Строка64 - обычная строка, с которой можно делать все, что угодно.
В конце статьи приведена функция
Преобразовать64(Строка64 = неопределено, Массив64 = неопределено) , которая преобразовывает строку в массив байтов, и обратно.
Для того, чтобы получить массив байтов из строки, вызываем ее так:
Код 1C v 8.2 УП Массив64 = Преобразовать64 ( Строка64 , ) ;
Для обратного преобразования вызываем так:
Код 1C v 8.2 УП Строка64 = Преобразовать64 ( , Массив64 ) ;
Преобразовать строку в двоичные данные можно при помощи функции Base64Значение(Строка64)
Все указанные функции, кроме Преобразовать64, являются встроенными функциям платформы.
Далее листинг функции Преобразовать64:
Код 1C v 8.2 УП
&НаСервере
Функция Преобразовать64(Строка64 = неопределено, Массив64 = неопределено)
Таб64 = Новый ТаблицаЗначений;
Таб64 . Колонки. Добавить( "Код" ) ;
Таб64 . Колонки. Добавить( "Символ" ) ;
Нпп = 0 ;
Для Код = КодСимвола( "A" ) По КодСимвола( "Z" ) Цикл
стр = Таб64 . Добавить( ) ;
стр. Код = Нпп;
стр. Символ = Символ( Код) ;
Нпп = Нпп + 1 ;
КонецЦикла ;
Для Код = КодСимвола( "a" ) По КодСимвола( "z" ) Цикл
стр = Таб64 . Добавить( ) ;
стр. Код = Нпп;
стр. Символ = Символ( Код) ;
Нпп = Нпп + 1 ;
КонецЦикла ;
стр = Таб64 . Добавить( ) ;
стр. Код = Нпп;
стр. Символ = "0" ;
Нпп = Нпп + 1 ;
Для Код = 1 По 9 Цикл
стр = Таб64 . Добавить( ) ;
стр. Код = Нпп;
стр. Символ = Формат( Код, "ЧЦ=1; ЧДЦ=0" ) ;
Нпп = Нпп + 1 ;
КонецЦикла ;
стр = Таб64 . Добавить( ) ;
стр. Код = Нпп;
стр. Символ = "+" ;
Нпп = Нпп + 1 ;
стр = Таб64 . Добавить( ) ;
стр. Код = Нпп;
стр. Символ = "/" ;
Если Массив64 = неопределено Тогда
Если Строка64 = неопределено Тогда
Сообщить( "неверный вызов функции" ) ;
Возврат неопределено ;
КонецЕсли ;
Строка64 = СтрЗаменить( Строка64 , Символ( 10 ) , "" ) ;
Строка64 = СтрЗаменить( Строка64 , Символ( 13 ) , "" ) ;
Если СтрДлина( Строка64 ) % 4 < > 0 Тогда
Сообщить( "длина строки на входе должна быть кратна 4" ) ;
Сообщить( СтрДлина( Строка64 ) ) ;
Возврат неопределено ;
КонецЕсли ;
Кол4 = Цел( СтрДлина( Строка64 ) / 4 ) ;
РазмерМ = Кол4 * 3 ;
Если Прав( Строка64 , 2 ) = "==" Тогда
РазмерМ = РазмерМ - 2 ;
ИначеЕсли Прав( Строка64 , 1 ) = "=" Тогда
РазмерМ = РазмерМ - 1 ;
КонецЕсли ;
Массив64 = Новый Массив( РазмерМ) ;
Для А = 1 По Кол4 Цикл
Число3 = 0 ;
Для Б = 1 По 4 Цикл
Буква1 = Сред( Строка64 , ( А- 1 ) * 4 + Б, 1 ) ;
Если Буква1 = "=" Тогда
Код4 = 0 ;
Иначе
стрН = Таб64 . Найти( Буква1 , "Символ" ) ;
Если стрН = Неопределено Тогда
Сообщить( "ошибка при поиске " + КодСимвола( Буква1 ) ) ;
Иначе
Код4 = стрН. Код;
КонецЕсли ;
КонецЕсли ;
Число3 = Число3 * 64 + Код4 ;
КонецЦикла ;
Ост = Число3 % 256 ;
Индекс = ( А- 1 ) * 3 + 2 ;
Если Индекс < = РазмерМ - 1 Тогда
Массив64 [Индекс] = Ост;
КонецЕсли ;
Число3 = ( Число3 - Ост) / 256 ;
Ост = Число3 % 256 ;
Индекс = ( А- 1 ) * 3 + 1 ;
Если Индекс < = РазмерМ - 1 Тогда
Массив64 [Индекс] = Ост;
КонецЕсли ;
Число3 = ( Число3 - Ост) / 256 ;
Ост = Число3 % 256 ;
Массив64 [( А- 1 ) * 3 + 0 ] = Ост;
КонецЦикла ;
Возврат Массив64 ;
Иначе
Строка64 = "" ;
Кол3 = Цел( Массив64 . Количество( ) / 3 ) ;
Если Массив64 . Количество( ) % 3 < > 0 Тогда
Кол3 = Кол3 + 1 ;
КонецЕсли ;
Для А = 1 По Кол3 Цикл
Число3 = Массив64 [( А- 1 ) * 3 ];
Если ( А- 1 ) * 3 + 1 < = Массив64 . ВГраница( ) Тогда
Код3 = Массив64 [( А- 1 ) * 3 + 1 ];
Иначе
Код3 = 0 ;
КонецЕсли ;
Число3 = Число3 * 256 + Код3 ;
Если ( А- 1 ) * 3 + 2 < = Массив64 . ВГраница( ) Тогда
Код3 = Массив64 [( А- 1 ) * 3 + 2 ];
Иначе
Код3 = 0 ;
КонецЕсли ;
Число3 = Число3 * 256 + Код3 ;
Ост4 = Число3 % 64 ;
Число3 = ( Число3 - Ост4 ) / 64 ;
Ост3 = Число3 % 64 ;
Число3 = ( Число3 - Ост3 ) / 64 ;
Ост2 = Число3 % 64 ;
Число3 = ( Число3 - Ост2 ) / 64 ;
Ост1 = Число3 % 64 ;
Число3 = ( Число3 - Ост1 ) / 64 ;
стрН = Таб64 . Найти( Ост1 , "Код" ) ;
Если стрН = неопределено Тогда
Сообщить( "Ошибка при поиске" ) ;
Иначе
Строка64 = Строка64 + стрН. Символ;
КонецЕсли ;
стрН = Таб64 . Найти( Ост2 , "Код" ) ;
Если стрН = неопределено Тогда
Сообщить( "Ошибка при поиске" ) ;
Иначе
Строка64 = Строка64 + стрН. Символ;
КонецЕсли ;
стрН = Таб64 . Найти( Ост3 , "Код" ) ;
Если стрН = неопределено Тогда
Сообщить( "Ошибка при поиске" ) ;
Иначе
Строка64 = Строка64 + стрН. Символ;
КонецЕсли ;
стрН = Таб64 . Найти( Ост4 , "Код" ) ;
Если стрН = неопределено Тогда
Сообщить( "Ошибка при поиске" ) ;
Иначе
Строка64 = Строка64 + стрН. Символ;
КонецЕсли ;
КонецЦикла ;
Если Массив64 . Количество( ) % 3 = 1 Тогда
Строка64 = Лев( Строка64 , СтрДлина( Строка64 ) - 2 ) + "==" ;
ИначеЕсли Массив64 . Количество( ) % 3 = 2 Тогда
Строка64 = Лев( Строка64 , СтрДлина( Строка64 ) - 1 ) + "=" ;
КонецЕсли ;
Возврат Строка64 ;
КонецЕсли ;
КонецФункции
Просто
открыть форму обработки можно так:
Код 1C v 8.2 УП &НаКлиенте
Процедура ОткрытьОбработку(Команда)
ОткрытьФорму( "Обработка.ОбработкаВводБланкЗаказа.Форма" ) ;
КонецПроцедуры
А вот
открыть форму обработки с передачей параметров :
Код 1C v 8.2 УП ПараметрыФормы = Новый Структура;
ПараметрыФормы. Вставить( "ДокСсылка" , НужнаяСсылка) ;
ОткрытьФорму( "Обработка.ПечатьНаправления.Форма" , ПараметрыФормы) ;
А в форме обработки, которую
открыли , эта ссылка будет доступна через коллекцию "
Параметры ".
Т.е. так:
Код 1C v 8.2 УП Параметры. ДокСсылка
В обработчике
ПриСозданииНаСервере() можно проверить наличие переданных параметров с помощью
Код 1C v 8.2 УП Если Параметры. Свойство( "ЛюбойПараметр" ) Тогда
КонецЕсли
Внимание! : Параметры формы доступны только в событии формы "ПриСозданииНаСервере". Т.е. в других процедурах ты с этой ссылкой работать не получится!
Тут два варианта:
1) Создать реквизит формы, допустим, с именем "СсылкаНаДокумент". И в событии "ПриСозданииНаСервере" заполнить этот реквизит.
Код 1C v 8.2 УП СсылкаНаДокумент = Параметры. ДокСсылка;
И дальше уже работать с ним.
2) Создать не реквизит формы, а параметр (закладка "Параметры" - там же рядом с закладками "Реквизиты" и "Команды"). Назвать его надо будет так же, как ключ структуры, используемый в коде открытия формы (в моем примере - "ДокСсылка"). И в свойствах этого параметра установить флаг "Ключевой параметр". Тогда к этому параметру можно будет обращаться так, как я писал выше -
Параметры.ДокСсылка
Но уже не только в событии "
ПриСозданииНаСервере ", а в любой процедуре модуля формы.
Еще посмотрите: Как программно открыть внешнюю обработку?