Имя: Пароль:
1C
1C 7.7
v7: Из XML Расходная накладная
0 mcwolf
 
15.10.13
21:56
Доброго времени суток! Уважаемые гуру подскажите чайнику =)
Питаюсь сделать обработку в 1с 7.7 Торговля+Склад, но что-то не выходит до конца доделать опыта не хватает (не судите строго я только начал изучать)
Обработка:

//Ограничения на входящие файлы XML:                        
//1) В первой строке обязателен заголовок XML вида <?xml version="1.0" encoding="windows-1251"?>    .
//2) Каждый тег должен быть записан в отдельной строке. Возможны отступы от начала строки и пустые строки.
//3) Значения атрибутов - строго в двойных кавычках.
//4) Не поддерживаются текстовые значения (любые значения можно передавать только через атрибуты).    
//5) Комментарии и "подобные им" элементы XML не поддерживаются.


перем xml_fso;
перем xml_file;
перем xml_ИмяТега;
перем xml_СписокАтрибутов;
перем xml_сз;  

///////////////////////////////////////////////////////////////////////
//Открывает XML-файл в режиме "только чтение"      
Процедура xml_ОткрытьФайл(прм_ИмяФайла)
//    прм_ИмяФайл="+ПутьФайла+";
//прм_ИмяФайла - имя файла XML (укажите полный путь и расширение .XML).


        xml_fso=СоздатьОбъект("Scripting.FileSystemObject");

        xml_file=xml_fso.OpenTextFile(прм_ИмяФайла, 1, 0, 0); //Открываем файл в режиме "только чтение"          
        стр=xml_file.ReadLine(); //Читаем заголовок XML вида <?xml version="1.0" encoding="utf-8"?>.
    
        Если Найти(стр,"<?xml")=0 Тогда
                Сообщить("Неправильный файл XML "+прм_ИмяФайла,"!"); а=10/0;        
        КонецЕсли;
        Если Найти(стр,"utf-8")=0 Тогда
                Сообщить("Требуется кодировка UTF-8 файла XML "+прм_ИмяФайла,"!"); а=10/0;
        КонецЕсли;
        xml_СписокАтрибутов=СоздатьОбъект("СписокЗначений");
        xml_сз=СоздатьОбъект("СписокЗначений");    
КонецПроцедуры  // xml_ОткрытьФайл

///////////////////////////////////////////////////////////////////////                    

//Считывает следующий тег XML.
//Возвращает 1, если тег прочитан и 0 - если был достигнут конец файла.                    

//Заполняет переменную xml_ИмяТега именем считанного тега в формате "<ИмяТега>".            

Функция xml_Прочитать(прм_ОжидаемыеТеги="")
//Если вы используете параметр прм_ОжидаемыеТеги, то заполните его списком тегов
//через запятую, которые могут быть считаны в данный момент (это позволяет проверять
//структуру файла XML и сделать более ясным считывающий код).

        xml_СписокАтрибутов.УдалитьВсе();
        стр="";
        Пока стр="" Цикл
                Если xml_file.AtEndOfStream=1 Тогда
                        Возврат 0; //тег не был прочитан, т.к. достигнут конец файла
                КонецЕсли;
                стр=СокрЛП(xml_file.ReadLine());
        КонецЦикла; //цикл, чтобы пропустить пустые строки

        Если Найти(стр,"=")=0 Тогда //Случай, когда нет атрибутов
                xml_ИмяТега=СокрЛП(стр);
        Иначе
                //Разбиваем тег на структуру, удобную для ИзСтрокиСРазделителями()    

                стр=СтрЗаменить(стр,"""",""",""");
                стр=""""+стр+"""";

                сз=xml_сз;
                сз.УдалитьВсе();
                сз.ИзСтрокиСРазделителями(стр);    
                
                //В первом элементе списка у нас и имя тега, и имя первого атрибута. Разделим их.
                зн=сз.ПолучитьЗначение(1);
                поз=Найти(зн , " ");
                xml_ИмяТега =СокрЛП(Лев(зн, поз)); //Выделим имя тега    


                xml_ИмяТега =xml_ИмяТега+">";
                
                //Выделим и обновим имя первого атрибута

                зн =СокрЛП(Сред(зн, поз));
                сз.УстановитьЗначение(1,зн);

                //Удаляем завершающий элемент списка /> или >.

                сз.УдалитьЗначение(сз.РазмерСписка());    

                //Переводим наш список значений в более удобный формат                
                i=1; //позиция в списке сз
                рс=сз.РазмерСписка();
                Пока i<=рс Цикл    
                        имя=сз.ПолучитьЗначение(i);
                        имя=СокрЛП(СтрЗаменить(имя,"=",""));    
                        зн=сз.ПолучитьЗначение(i+1);    
                        //Заменяем спецсимволы XML
                        зн=СтрЗаменить(зн,"&"+"quot"+";","""");    
                        зн=СтрЗаменить(зн,"&"+"apos"+";","'");
                        зн=СтрЗаменить(зн,"&"+"lt"+";","<");
                        зн=СтрЗаменить(зн,"&"+"gt"+";",">");
                        зн=СтрЗаменить(зн,"&"+"amp"+";","&");

                        xml_СписокАтрибутов.ДобавитьЗначение(зн,имя);
    
                                                i=i+2;
                КонецЦикла;
        КонецЕсли;

        Если ПустаяСтрока(прм_ОжидаемыеТеги)=0 Тогда    

//Проверяем наличие имени тега в списке ожидаемых тегов (если надо контролировать структуру)
      
                //*Если Найти(прм_ОжидаемыеТеги,xml_ИмяТега)=0 Тогда
                //*        Сообщить("Неожиданный тег "+xml_ИмяТега+" в строке "+xml_file.line); a=10/0;
                //*КонецЕсли;
        КонецЕсли;

        Возврат 1; //успешное чтение тега
КонецФункции    // xml_Прочитать
                
///////////////////////////////////////////////////////////////////////          
//Получает значение атрибута считанного тега по имени атрибута.          
//Если надо получить атрибут по его номеру, читайте список значений xml_СписокАтрибутов                          
                
Функция xml_ПолучитьАтрибут(прм_ИмяАтрибута)      
        Возврат xml_СписокАтрибутов.Получить(прм_ИмяАтрибута);                        
КонецФункции    // xml_ПолучитьАтрибут
                
///////////////////////////////////////////////////////////////////////
//Закрывает открытый файл XML. По завершении работы с файлом его необходимо закрыть.
Функция xml_Закрыть()
        xml_file.Close();
КонецФункции    // xml_Закрыть
                
                
                
//*******************************************      
//Тестовая процедура, которая считывает XML файл в справочник Товаров.                                            
Процедура Выполнить()                              
        стрИмяФайла=КаталогИБ()+"XML\tovar.xml";  
                
        спр=СоздатьОбъект("Справочник.Номенклатура");
        
        НачатьТранзакцию();        //Для ускорения        
        сч=0;              //Для ускорения    
        Сообщить("Начало чтения XML: "+ТекущееВремя());    
        xml_ОткрытьФайл(стрИмяФайла);
        
        xml_Прочитать("<gw_srv_rsp>");
        xml_Прочитать("<DAT>");
        xml_Прочитать("</P>");

        
        СпрТовары=СоздатьОбъект("Справочник.Номенклатура");
        спрР=СоздатьОбъект ("Документ");
        спрР=СоздатьОбъект("Документ.РасходнаяНакладная");
        спрР.Новый ();
  
        Пока xml_Прочитать("<DAT>,<P>,</P>,<E>,<N>,<TS>,</gw_srv_rsp>")=1 Цикл
                сч=сч+1; //Для ускорения
                Если сч%1000=0 Тогда       //Для ускорения
                        ЗафиксироватьТранзакцию(); //Для ускорения
                        НачатьТранзакцию();//Для ускорения
                    КонецЕсли;//Для ускорения

                Если xml_ИмяТега="</gw_srv_rsp>" Тогда
                        Прервать;
                КонецЕсли;
                
                
                Код=Число(xml_ПолучитьАтрибут("C"));
                Товар=xml_ПолучитьАтрибут("NM");
                Количество=Число(xml_ПолучитьАтрибут("Q"));
                Цена=Число(xml_ПолучитьАтрибут("PRC"));
                ДатаОплаты=xml_ПолучитьАтрибут("ДатаОплаты");
                КолВоВНанк=Число(xml_ПолучитьАтрибут("N"));


                
                    спрР=СоздатьОбъект ("Документ");
                       спрР=СоздатьОбъект("Документ.РасходнаяНакладная");
                       
                       спрР.ВыбратьСтроки();
        
                    спрР.Новый ();
                
                    

                       спрР.ВыбратьСтроки();

                    
                        спрР.НоваяСтрока ();

                    
                    
                
                спрР.Товар = СпрТовары.ТекущийЭлемент ();
                спр=СоздатьОбъект("Справочник.Номенклатура");
                Если спр.НайтиПоНаименованию(Товар)=1 Тогда
                    //Предупреждение("Найденный элемент справочника имеет код "+спр.ТекущийЭлемент().ПолнНаименование);
                    Сообщить ("Добавлена строка с товаром: " +спр.ТекущийЭлемент().ПолнНаименование);
                
                    спрР.Товар = спр.ТекущийЭлемент();
                    спрР.Количество = Количество/1000;
                    спрР.ЦенаСНДС = Цена;
                    спрР.ЦенаБезНДС = Цена-(Цена*20/100);
                    спрР.СуммаБезНДС =(Количество/1000)*(Цена-(Цена*20/100));
                    спрР.СуммаСНДС = (Количество/1000)*Цена;
                    спрР.ДатаОплаты = xml_ПолучитьАтрибут("TS"); //ДатаОплаты;
                    
                    Если  xml_Прочитать("</DAT>")=1 Тогда
                    спрР.Записать();
                    

                        Продолжить;
                    Иначе
                        //Предупреждение("Элемент с заданным наименованием не найден");
                        Сообщить ("Элемент с заданным наименованием не найден: " +Товар);
                        Продолжить;
                    КонецЕсли;
                КонецЕсли;
                
        КонецЦикла;     //по элементам XML
        
        
        xml_Закрыть();
        Сообщить("Обработка завершена! "+ТекущееВремя(),"i");
        ЗафиксироватьТранзакцию();                                 //Для ускорения
        
    
КонецПроцедуры  


процедура приОткрытии()
      
    ПутьФайла = КаталогИБ()+"XML\tovar.xml";
    
КонецПроцедуры    






и собственно сам XML:

<?xml version="1.0" encoding="utf-8"?>
<gw_srv_rsp>
<select>
<FISC V="1">
<EJ ID="ПБ4101217109">

<DAT DI="20" FN="2659024340" KI="1" TN="ПН 164775926121" V="1" ZN="ПБ4101217109">
<C T="0">
<P C="59" CD="2000000059013" N="1" NM="Диск дл циркулярної пилки KT 125 (24T)" PRC="2440" Q="1000" SM="2440" TX="1"></P>
<P C="60" CD="2000000060019" N="2" NM="Диск дл циркулярної пилки KT 125 (40T)" PRC="3242" Q="1000" SM="3242" TX="1"></P>
<P C="1270" CD="2000001270011" N="3" NM="Свердло по металу P9 (Росія) d.4.2мм" PRC="646" Q="10000" SM="6460" TX="1"></P>
<M N="4" SM="12142" T="0">
</M>
<E CS="1" N="5" NO="4" SM="12142">
<TX DTPR="0.00" TX="1" TXPR="20.00" TXSM="2024" TXTY="0"></TX>
</E>
</C>
<TS>20130803152414</TS>
</DAT><DAT DI="159" FN="2659024340" KI="1" TN="ПН 164775926121" V="1" ZN="ПБ4101217109">
<C T="0">
<P C="31" CD="2000000031019" N="1" NM="Клей SOMA FIX (супер клей) 3гр. 808E" PRC="289" Q="3000" SM="289" TX="1"></P>
<P C="227" CD="2000000227016" N="2" NM="Мом 25 Клеюча суміш для плитки Момент, 25 кг" PRC="4079" Q="1000" SM="4079" TX="1"></P>
<M N="2" SM="289" T="0"></M>
<E CS="1" N="3" NO="108" SM="289">
<TX DTPR="0.00" TX="1" TXPR="20.00" TXSM="48" TXTY="0"></TX>
</E>
</C>
<TS>20130810124726</TS>
</DAT>
</EJ>
</FISC>
</select>
</gw_srv_rsp>

Получается есть теги <DAT>....</DAT> между этих тегов есть <P>...</P>
но их может быть несколько но добавляет только первый. Как сделать так  чтоб расходная накладная создавалась со всеми позициями указаними в тегах <DAT>....</DAT>?
1 Тьма
 
15.10.13
22:36
Для начала было бы неплохо исправить некоторые ошибки
1. По условию
Если  xml_Прочитать("</DAT>")=1 Тогда
предполагается, что xml_Прочитать возвращает 0, если данный тег не найден в следующей строке. Однако 0 возвращается только в случае конца файла.
2. Делать цикл по условию на итератор (пока получить строку файла) и внутри цикла менять этот итератор (уже упомянутое условие) - дурной тон. У тебя каждая вторая строка в файле из-за этого не обрабатывается.
3. Ветвление с сообщением
Сообщить ("Элемент с заданным наименованием не найден: " +Товар);
не в том условии. Там 2 Если и по смыслу это счастье должно быть в первом.
4. Поиск по наименованию - это плохо. Там код в файле для этого есть. Разумеется, код не должен быть доступен пользователю для изменения.
П.С.
Лично я разбор этого файла со шлюза делаю так:
После посылки АШТТП запроса получаю ответ в одну переменную и работаю с ней. В этой переменной ищу теги DAT и /DAT, выделяю таким образом один чек. Уже в этом чеке ищу строчку "P C=" (или можно так же выделять по очереди по тегу <Р> </Р>) и уже в нем ищу код, цену и количество. Там будут еще нюансы, связанные с возвратными чеками, отменой чека, скидками в чеке (если в Т400 не запрещены скидки, что стоит сделать). Возможно, будет еще много других нюансов, так как описания формата этого файлика в глаза не видел :)
2 mcwolf
 
15.10.13
23:00
Спасибо за столь обширный ответ. Я мало чего понял :))  но  понял что я еще очень далеко от истины =)
3 mcwolf
 
15.10.13
23:57
И еще вопросик есть компонента ecrT400.dll есть пример работы с 1С 8
Код проверен на версии ecrT400.dll — 1.0.4.515, 1С версии 8.2.16.362.

Приведенный пример кода написан для управляемого приложения.

//подключение компоненты

ПодключитьВнешнююКомпоненту(«ecrmini.t400?);

//создаем соединение с компонентой для отправки команд

Connection = Новый COMОбъект(«ecrmini.t400?);

//команда открытия порта

Result = Connection.t400me(«open_port;1;115200?);
Если НЕ Result Тогда
КодОшибки = Connection.get_last_error();
Результат = «Ошибка соединения МИНИ Т400: «+КодОшибки;
КонецЕсли;

Аналогично запускаются и остальные команды, методом t400me().


Может кто-то видел код для 7-ки?
4 Тьма
 
16.10.13
09:15
(2)Я заметил, что ты не используешь 1с-ные функции работы со строками Найти и Сред. Может, с ними будет попроще? Что-то типа:
Если Найти(ТекСтрока,"<P>")<>0 тогда //строка продажи из чека
Поз1=найти(ТекСтрока," C=");//позиция, с которой начинается код
Поз2=Найти(Текстрока," CD=");//позиция, с которой начинается штрихкод
Код=Сред(ТекСтрока,Поз1+4,Поз2-Поз1-5);
///и так далее
(3)Делаю все обычным АШТТП запросом, без ВК. Вот так продажи получаю. Правда, с четвертой версией шлюза этот код перестал работать, но меня пока устраивает третья :)
    Дата1=""+ДатаГод(НачДата)+Прав("00"+ДатаМесяц(НачДата),2)+Прав("00"+ДатаЧисло(НачДата),2)+"0000";
    Дата2=""+ДатаГод(КонДата)+Прав("00"+ДатаМесяц(КонДата),2)+Прав("00"+ДатаЧисло(КонДата),2)+"2359";
    Сервер="http://10.0.0.101:12702/lsoft";;
    WinHttp=СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
    WinHttp.Open("POST",Сервер,0);    
    WinHttp.setRequestHeader("Content-type", "text/xml");
    WinHttp.setRequestHeader("Content-length", "34077");
    xml="<?xml version="+Симв(34)+"1.0"+Симв(34)+" encoding="+Симв(34)+"utf-8"+Симв(34)+"?>"+Разделительстрок;
    xml=xml+"<srv_req>"+Разделительстрок;
    xml=xml+"<select from ="+Симв(34)+Дата1+Симв(34)+" to="+Симв(34)+Дата2+Симв(34)+">"+Разделительстрок;
    спр1=создатьобъект("Справочник.КассовыеАппараты");
    спр1.выбратьэлементы();
    Пока спр1.получитьэлемент()=1 цикл
        Если ПустоеЗначение(Спр1.Магазин)=1 Тогда
            продолжить;
        КонецЕсли;
        Если сокрлп(Спр1.Фискальныйномер)="" Тогда
            продолжить;
        КонецЕсли;
        Если спр1.пометкаудаления()=1 Тогда
            продолжить;
        КонецЕсли;  
        Если (магазин.выбран()=1)и(Спр1.Магазин<>Магазин) Тогда
            продолжить;
        КонецЕсли;      
        Если ПустоеЗначение(Спр1.касса)=1 Тогда
            продолжить;
        КонецЕсли;
        xml=xml+"<dev sn="+Симв(34)+ПреобразоватьСтрокуВУТФ8(сокрлп(Спр1.Фискальныйномер))+Симв(34)+"/>"+Разделительстрок;
    конеццикла;
    xml=xml+"</select>"+Разделительстрок;
    xml=xml+"</srv_req>";
    Тк=создатьобъект("Текст");
    Тк.ДобавитьСтроку(xml);
    тк.записать("c:\temp\zapr.xml");    
    WinHttp.SetTimeouts(1000000,1000000,1000000,1000000);
    WinHttp.Send(xml);
    WinHttp.WaitForResponse(-1);
    ответ=WinHttp.ResponseText;
    ответ1=WinHttp.StatusText;
5 Тьма
 
16.10.13
09:16
+(4)И да, ПреобразоватьСтрокуВУТФ8 можно заменить просто на сокрлп - там с кодировками некая шняга, в заголовке указан УТФ, а принимает файл только в АНСИ. Хотя если руками загружать на шлюз, нужен УТФ. :)
6 Тьма
 
16.10.13
09:20
(3)Если сильно хочешь через ВК, то отличия для 7.7 невелики:
вместо
ПодключитьВнешнююКомпоненту(«ecrmini.t400?);
пишешь
ЗагрузитьВнешнююКомпоненту(ПутьКДЛЛФайлуВнешнейКомпоненты);
и вместо
Connection = Новый COMОбъект(«ecrmini.t400?);
пишешь
Connection = СоздатьОбъект("ecrmini.t400");
7 mcwolf
 
16.10.13
21:05
Насколько я понял можно еще юзать ecrT400.dll и можно будет вытащить нужные данные со шлюза? Или есть другие способы чтения отчётов Мини Т400, потому что за день много продаж а вручную вбивать пипец как долго...
8 Тьма
 
16.10.13
21:16
(7)Есть и другие. В (4) есть пример ХТТП-запроса к шлюзу. Также этот метод описан в документации по ссылке http://unisystem.ua/ru/product/avtomat/support/shluz-unisystem.html. Кроме того, непосредственно в интерфейсе шлюза можно выгрузить ручками же хмл-файл с продажами или же эксель-файл с теми же данными - если работа с экселем по каким-то причинам представляется более предпочтительной.
9 mcwolf
 
16.10.13
22:33
Если тебе не сложно можешь показать как пользоваться твоими указаниями(4) на моём примере?
10 mcwolf
 
16.10.13
22:37
Давно работаешь с мини т400? Как загружаешь товары обработкой?
11 mcwolf
 
17.10.13
00:05
Могу поделится обработкой :)
12 Тьма
 
17.10.13
09:15
(9)Ну... а что неясно в (4)? По поводу твоего примера - надо заменить
////
                   Если  xml_Прочитать("</DAT>")=1 Тогда
                    спрР.Записать();
                    

                        Продолжить;
                    Иначе
                        //Предупреждение("Элемент с заданным наименованием не найден");

                        Сообщить ("Элемент с заданным наименованием не найден: " +Товар);
                        Продолжить;
                    КонецЕсли;
////////
на
/////
спрР.Записать();
///////
это не вполне оптимально, но работать должно лучше.
(10)С февраля 2013. На шлюз третьей версии ХТТП-запросом, единственно что 1с не умеет посылать ХТТП-запросы размером более 500Кб, по подсказке с этого форума отправляю vbs-скриптом, который, впрочем, все равно создается и вызывается из 1С. На шлюз четвертой - формируется хмл и оператор ручками на шлюзе его грузит.
(11)Их есть у меня :)
13 mcwolf
 
17.10.13
10:19
(12) Если сделать замену ка ты говоришь то на каждую позицию создается новая накладная, а нужно чтоб создавалась накладная согласно <DAT>...</DAT>, Если поставить "Если  xml_Прочитать("</DAT>")=1 Тогда" то года оно разбивает по <DAT>...</DAT> но считывает только первые <P> а остальные пропускает.
14 monsterZE
 
17.10.13
10:43
все не читал.. но в чем проблема? =)
читаешь строки
при <DAT> поднимаешь флаг нового документа
пока не </DAT>
пихаешь строки в документ по <p></p>
вот тебе для примера.. что-то аналогичное
только у меня собирается в тз и по колонкам тз_на_форме выводится нужное (чтоб прощее добавлять новое)
    Состояние("Загрузка файла обмена ПП");
    СтрокТФ = ТФ.КоличествоСтрок();
    НовоеПП = 0;
    
    Для ъ=1 По СтрокТФ Цикл
        ТФСтр = ТФ.ПолучитьСтроку(ъ);
        
        Если СтрДлина(ТФСтр)=0 Тогда
            Продолжить;
        КонецЕсли;
        
        Если НовоеПП=0 Тогда
            // начало ПП
            Если Найти(ТФСтр,"СекцияДокумент=Платежное поручение")=1 тогда
                НовоеПП = 1;
                ТабТекПП.Очистить();
                ТабТекПП.НоваяКолонка("ПарамИмя");
                ТабТекПП.НоваяКолонка("ПарамЗнач");
            КонецЕсли;
        Иначе
            // конец ПП
            Если Найти(ТФСтр,"КонецДокумента")=1 тогда
                ВыгрВТаб(ТабТекПП,СписокКолонокПП,ВремТаб);
                НовоеПП = 0;
            Иначе
                // строки ПП
                Если ДобавитьЗначВТаб(ТабТекПП,ТФСтр,"=")=1 Тогда
                    Предупреждение("Ошибка в структуре файла обмена, текущее ПП пропущено",5);
                    
                    Сообщить("-- Ошибочное ПП --");
                    ТабТекПП.ВыбратьСтроки();
                    Пока ТабТекПП.ПолучитьСтроку()=1 Цикл
                        Сообщить(ТабТекПП.ПарамИмя+"="+ТабТекПП.ПарамЗнач);
                    КонецЦикла;
                    
                    НовоеПП = 0;
                КонецЕсли;    
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
15 Тьма
 
17.10.13
19:19
(13)Убери из цикла
///////
                    спрР=СоздатьОбъект ("Документ");
                       спрР=СоздатьОбъект("Документ.РасходнаяНакладная");
                      
                       спрР.ВыбратьСтроки();
        
                    спрР.Новый ();
                
                    

                       спрР.ВыбратьСтроки();
/////////
и не будет на каждую строчку новый документ создавать
16 mcwolf
 
17.10.13
23:45
(15) В принципе то оно так но теперь все записывается в одну накладную... а нужно чтоб на каждый <DAT> создавалась новая накладная.
17 mcwolf
 
18.10.13
00:11
(14) Спасибо Вам за ответ но я вернусь к первому посту "не судите строго я только начал изучать"
18 mcwolf
 
18.10.13
01:41
(16) Ах да и еще забыл записывает в одну накладную и все равно только первые позиции <P> остальные пропускает...
19 Тьма
 
18.10.13
09:24
(18)Сейчас досмотрелся - это чудо юнисистемское пишет каждый чек в одну строчку. Ну а твой код из каждой строчки берет только один товар. Так что твоя процедурка xml_Прочитать этого не отработает и придется тебе писать два цикла - один по строкам, а второй по поиску в текущей строке открывающего и закрывающего тега <P>. Потом уже вырванную серединку можешь скормить своей процедуре. После нахождения первого закрывающего тега обрезаешь строку справа и ищешь в новой строке и т.д. пока все теги <P> не будут найдены. Смотри описание функция работы со строками Найти и Сред.
20 mcwolf
 
19.10.13
10:15
(19) Будем читать...