.Net в 1С. На примере использования HTTPClient, AngleSharp. Удобный парсинг сайтов с помощью библиотеки AngleSharp, в том числе с авторизацией аля JQuery с использованием CSS селекторов. Динамическая компиляция

Публикация № 466196

Разработка - Практика программирования

C# .Net parser AngleSharp

110
Часто приходится парсить сайты, в том числе с авторизацией, перескакивая со страницы на страницу по ссылкам. Тот, кто занимался вэб программированием, знает, как удобно использовать JQuery и CSS селекторы. На .Net написана очень удобная библиотека AngleSharp. Я покажу, как с её помощью можно значительно облегчить себе труд.

Это продолжение статьи .Net в 1С. Примеры использования HTTPClient,AngleSharp. Асинхронные HTTP запросы, отправка Post нескольких файлов multipart/form-data,сжатие трафика с использованием gzip, deflate,удобный парсинг сайтов итд

https://github.com/AngleSharp/AngleSharp  это .Net библиотека для разбора HTML файлов в стиле CSS селекторов, аналогично использованию JQuery.  Которая также поддерживает CSS и JavaScript. Но библиотека поддержки JavaScript пока плющевая и давно не обновлялась https://github.com/AngleSharp/AngleSharp.Scripting

На первой же странице есть пример получения названий всех серий сериала "Теория большого взрыва"

// устанавливаем параметры для использования разбора документа
var config = Configuration.Default.WithDefaultLoader();
// Устанавливаем адрес страницы сайта
var address = "https://en.wikipedia.org/wiki/List_of_The_Big_Bang_Theory_episodes";
// загружаем страницу и разбираем её
var document = await BrowsingContext.New(config).OpenAsync(address);
// Используем CSS селектор для получения строк таблицы с классом  и выбрать из этой строки 3 колонку 
var cellSelector = "tr.vevent td:nth-child(3)";
// Получим все ячейки
var cells = document.QuerySelectorAll(cellSelector);
//Выделим из ячеек текстовое содержимое
var titles = cells.Select(m => m.TextContent);

Красиво, не правда ли?

На 1С это будет выглядеть так

	
	config = AngleSharp_Configuration;
	Расширение=Врап.ПолучитьТип("AngleSharp.ConfigurationExtensions");
	config =Расширение.WithDefaultLoader(config);
            // Load the names of all The Big Bang Theory episodes from Wikipedia
          address = "https://en.wikipedia.org/wiki/List_of_The_Big_Bang_Theory_episodes";
            // Asynchronously get the document in a new context using the configuration
          document = Врап.ПолучитьТип("AngleSharp.BrowsingContext").New(config);
          BrowsingContextExtensions=Врап.ПолучитьТип("AngleSharp.BrowsingContextExtensions");
		  
		  document =BrowsingContextExtensions.OpenAsync(document,address).Result;
            // This CSS selector gets the desired content
          cellSelector = "tr.vevent td:nth-child(3)";
            // Perform the query to get all cells with the content
          cells = document.QuerySelectorAll(cellSelector);
            // We are only interested in the text - select it with LINQ

            Для каждого стр Из cells Цикл
			
			Сообщить(стр.TextContent)	
			
	    КонецЦикла; 

В предыдущей статье я уже показывал описание

Но повторю

// Сборку AngleSharp.dll поместить в каталог программы
//Для использования Scripting Api
    КатаогПрограммы=Врап.ПолучитьТип("System.AppDomain").CurrentDomain.BaseDirectory;
	ИмяСборкиAngleSharp=Врап.ПолучитьТип("System.IO.Path").Combine(КатаогПрограммы,"AngleSharp.dll");
	AngleSharp_Configuration=Врап.ПолучитьТипИзСборки("AngleSharp.Configuration",ИмяСборкиAngleSharp);
        parser = Врап.СоздатьОбъект("AngleSharp.Parser.Html.HtmlParser");

 

AngleSharp.dll можно поместить в любое место, но для динамической компиляции нужно, чтобы библиотека находилась в домене приложения(КаталогПрограммы). Об этом в конце статьи. Про CSS селекторы и их использование можно почитать здесь

http://anton.shevchuk.name/javascript/jquery-for-beginners-selectors

http://htmlbook.ru/css/nth-child

https://learn.javascript.ru/css-selectors

https://habrahabr.ru/post/51717/

http://webknowledge.ru/slozhnye-css-selektory-soderzhaschie-klass-i-id-elementov/

Теперь посмотрим, как можно получить тот же результат, но с использованием HTTPClient, и заполним данные в таблице

	stopWatch = Врап.СоздатьОбъект("System.Diagnostics.Stopwatch");
	
        stopWatch.Start();

	      Client = Врап.СоздатьОбъект(HttpClient);
              Client.BaseAddress = Врап.СоздатьОбъект("System.Uri","https://en.wikipedia.org");
              res = Client.GetStringAsync("wiki/List_of_The_Big_Bang_Theory_episodes").Result;

              parser = Врап.СоздатьОбъект("AngleSharp.Parser.Html.HtmlParser");
             //Just get the DOM representation
             document = parser.Parse(res);
             СелекторСтроки = "tr.vevent";
    Тз=новый ТаблицаЗначений;
    Колонки=Тз.Колонки;
    Колонки.Добавить("НомерСерии");
    Колонки.Добавить("НомерСерииВСезоне");
    Колонки.Добавить("Название");
    Колонки.Добавить("Режиссер");
    Колонки.Добавить("Автор");
    Колонки.Добавить("Дата");
    Колонки.Добавить("Код");
    Колонки.Добавить("Просмотров");

     Строки =document.QuerySelectorAll(СелекторСтроки);

     stopWatch.Stop();
	Сообщить("Скачка и парсинг");
	ВывестиВремя(stopWatch,истина);
	
	
	stopWatch.Restart();


           Для Каждого стр из Строки Цикл
		сч=0;
		стрТз=Тз.Добавить();
		Ячейки=стр.Cells;
				
		Для каждого Ячейка из Ячейки Цикл
				
		 стрТз[сч]=Ячейка.TextContent;
		 сч=сч+1;
		   Если сч=8 Тогда
			прервать
		   КонецЕсли;
		КонецЦикла
	   КонецЦикла;
		
	stopWatch.Stop();
	
	
	Сообщить("Время выполнения =");
	ВывестиВремя(stopWatch,истина);

	Тз.ВыбратьСтроку();	

 

Все прекрасно. Но меня ждало разочарование. Заполнение составляло 8 секунд. Решение я нашел. Но об этом попозже.

Надо отметить, что  QuerySelectorAll и QuerySelector можно применять к контейнерам поддерживающих интерфейс 

 

 
    public interface IParentNode
    {
       
        int ChildElementCount { get; }
        IHtmlCollection<IElement> Children { get; }
        IElement FirstElementChild { get; }
        IElement LastElementChild { get; }
        void Append(params INode[] nodes);
        void Prepend(params INode[] nodes);
        IElement QuerySelector(string selectors);
        [DomName("querySelectorAll")]
        IHtmlCollection<IElement> QuerySelectorAll(string selectors);
    }
}

 

Мы можем например задать селектор для строки. Например получить первый и третий элемент строки

 

Строки =document.QuerySelectorAll(СелекторСтроки);
    
           	Для Каждого стр из Строки Цикл
				//Ячейки=стр.Cells;
				 Ячейки=стр.QuerySelectorAll("th:nth-child(1),td:nth-child(3)");
				Для каждого Ячейка из Ячейки Цикл
				
				стрТз[сч]=Ячейка.TextContent;
			КонецЦикла
		КонецЦикла;

 

 Добавлю еще про коллекци.  

 public interface IHtmlCollection<T> : IEnumerable<T>, IEnumerable where T : IElement
    {
     
        T this[int index] { get; }
        T this[string id] { get; }
        int Length { get; }
    }

 К ним можно обращаться по номерe и по ID или атрибуту. Например

 

Строки =document.QuerySelectorAll(СелекторСтроки);
ВтораяСтрока=Строки.get_Item(1);

Пока покажу, как использовать селекторы. Возьмем ту же страницу, но выделим только ссылки на серии.

 

Client.BaseAddress = Врап.СоздатьОбъект("System.Uri","https://en.wikipedia.org");
	res = Client.GetStringAsync("wiki/List_of_The_Big_Bang_Theory_episodes").Result;
	
	document = parser.Parse(res);
	СелекторСтроки = "li.toclevel-2>a";
	Строки =document.QuerySelectorAll(СелекторСтроки);
	// Получим селекторы аннотации выделим текст и Хэш ссылку
      Для Каждого стр из Строки Цикл 
        Сообщить(Стр.TextContent + " "+стр.Hash); 
      КонецЦикла;

Теперь попробуем использовать форму поиска

Форма=document.QuerySelector("form#searchform");
	ссылка=	Форма.Action;
	
	структура=новый структура;
	Для каждого Элемент Из Форма.Elements  Цикл
		Элем=Врап.ПолучитьИнтерфейс(Элемент,"IHtmlInputElement");
		//Нужны только Input элементы
		//Выберем все элементы Input
		// и запишем их имена и значения
		Если Элем<> Неопределено Тогда
			структура.Вставить(Элем.Name,Элем.Value);
			Сообщить(Элем.Name+"="+Элем.Value);
			
		КонецЕсли; 
		
		
	КонецЦикла; 		
	структура.search="Кириллица";
	// Если удалить fulltext то произойдет Redirect
	// структура.Удалить("fulltext");
	Врап.ВСтроку(Элемент);
	сб=Врап.СоздатьОбъект(StringBuilder,ссылка+"?");
	//var uri = new Uri(builder.ToString(), dontEscape: true);
	
	// Создадим строку запроса. Для метода Get
	// так как Форма.Method=""
	Для каждого стр Из структура  Цикл
		
	   сб.AppendFormat("{0}={1}&",HttpUtility.UrlPathEncode(стр.Ключ),HttpUtility.UrlPathEncode(стр.Значение),0);
	
	КонецЦикла; 
	
	стр=сб.ToString(0,сб.Length-1); 
	Сообщить(стр);
	//Сделаем запрос по относительному пути
	//Так как основной путь уже прописан в BaseAddress
	res = Client.GetStringAsync(стр).Result;
	
	// Посмотрим результат
	// Можно посмотреть страницу используя например
	//http://filyanin.ru/8-vizualnyy-HTML-onlayn-redaktor.html
	Текст=Новый ТекстовыйДокумент;
	Текст.УстановитьТекст(res);
	Текст.Показать();
		
	document = parser.Parse(res);
	
	// Найдем результаты поиска по пути
	// ul с классом mw-search-results в первом потомке li и в первом потомке div и а
	CSSСелектор = "ul.mw-search-results>li>div>a";
	Строки =document.QuerySelectorAll(CSSСелектор);
	
	Для Каждого стр из Строки Цикл
		Сообщить(Стр.TextContent + " "+Стр.PathName);
		
	КонецЦикла; 

 

Очень часто приходится искать информацию на сайтах с авторизацией. При этом поля формы содежат дополнительные поля для верификации. 

Вот пример поиска нужного значения.

var configuration = Configuration.Default.WithDefaultLoader().WithCookies();
                var context = BrowsingContext.New(configuration);
                // откромем начальную страницу  
                await context.OpenAsync(WebsiteUrl);
                // Найдем ссылку содержашуюся в элементе a и классом log-in
                await context.Active.QuerySelector<IHtmlAnchorElement>("a.log-in").Navigate();
                // Установим элементам формы нужное значение и вызовем Submit
                await context.Active.QuerySelector<IHtmlFormElement>("form").Submit(new
                {
                    User = "User",
                    Password = "secret"
                });
                // Опять найдем нужную ссылку и перейдем на страницу с искомым значением
                await context.Active.QuerySelector<IHtmlAnchorElement>("a.secret-link").Navigate();
                // Получим это искомое значение 

 

Теперь перепишем все это с использованием HTTPClient

Клиент = Врап.СоздатьОбъект(HttpClient);
	Клиент.BaseAddress = Врап.СоздатьОбъект("System.Uri",WebsiteUrl);
	// Стоит отметить, что по умолчанию  HttpClient использует Cookie
	//Загрузим основную страницу
	res = Клиент.GetStringAsync("").Result;
    document = parser.Parse(res);
    // Найдем адрес страницы для авторизации
	
	Аннотация= document.QuerySelector("a.log-in");
    //Полный относительный путь Аннотация.PathName+Аннотация.Search
    // Но в данном случае Аннотация.Search просто нет
    // Если использовать BrowsingContext то полный путь содержится в Href

	res= Клиент.GetStringAsync(Аннотация.PathName).Result;
	 document = parser.Parse(res);
    // Найдем  элемент form для авторизации
	//В которой есть поле для верификации __RequestVerificationToken 
     Форма=document.QuerySelector("form");
	 Сообщить(Форма.Method);
	 d = Врап.СоздатьОбъект(Dictionary);
	 
	Для каждого Элемент Из Форма.Elements  Цикл
		Элем=Врап.ПолучитьИнтерфейс(Элемент,"IHtmlInputElement");
		//Нужны только Input элементы
		//Выберем все элементы Input
		// и запишем их имена и значения в словарь
		Если Элем<> Неопределено Тогда
			d.Add(Элем.Name, Элем.Value);
			Сообщить(Элем.Name+"="+Элем.Value);
			 
		КонецЕсли; 
		
		
	КонецЦикла; 	
	
	
            d.set_Item("User", "User");
            d.set_Item("Password", "secret");
			
			Контент=Врап.СоздатьОбъект(FormUrlEncodedContent,d);
		// Отправим пост запрос с данными формы	по адресу находящемся в Action
		резулт=Клиент.PostAsync(Форма.Action,Контент).Result;
		
		// И получим ответ
		res=резулт.Content.ReadAsStringAsync().Result;
		document = parser.Parse(res);

	// Найдем на этой странице ссылку на секретную страницу
     Аннотация= document.QuerySelector("a.secret-link");
	 res= Клиент.GetStringAsync(Аннотация.PathName).Result;
	  document = parser.Parse(res);
	  // Получим из первого параграфа искомое значение
	  Сообщить(document.QuerySelector("p").TextContent)

 

В C# есть удобный сахар в виде расширений. Например, код

Configuration.Default.WithDefaultLoader().WithCookies();

//На самом деле представляет собой 

 var configuration = AngleSharp.Configuration.Default;

            configuration=AngleSharp.ConfigurationExtensions.WithDefaultLoader(configuration);
            configuration = AngleSharp.ConfigurationExtensions.WithCookies(configuration);

// Так как функция WithDefaultLoader представляет функцию расширения
// так как первый параметр помечен как this 
// Что позволяет использовать этот метод через точку
public static IConfiguration WithDefaultLoader(this IConfiguration configuration, Action<LoaderService> setup = null, IEnumerable<IRequester> requesters = null);

 

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

Но, к сожалению, красивый код на C# превращается в монстра на 1С. Но зато есть примеры, как с этим бороться

/Получить типизированную дженерик функцию
//TElement QuerySelector<TElement>(this IParentNode parent, string selectors) 
Функция ПолучитьДжененрикМетодИнфо(тип,ИмяМетода,типПараметра)
	method = Врап.ТипКакОбъект(тип).GetMethod(ИмяМетода);
	generic = method.MakeGenericMethod(типПараметра);
	return generic;
	
КонецФункции

// Когда есть перегрузка методов нужно искать метод по имени и типам параметров
// Task<IDocument> Navigate<TElement>(this TElement element)
// string Text<T>(this T element)
Функция ПолучитьМетодИнфоОдинДженерикТип(тип,ИмяМетода,типПараметра)
	
	Для Каждого m in Врап.ТипКакОбъект(тип).GetMethods() Цикл
		
		параметры = m.GetParameters();
		if  (m.Name = ИмяМетода)   
			И (параметры.Length = 1)
			И (Врап.ТипКакОбъект(параметры.GetValue(0).ParameterType).IsGenericParameter)
			Тогда
			method = m;
			break;
		КонецЕсли
	КонецЦикла;
	generic = method.MakeGenericMethod(типПараметра);
	return generic;
	
КонецФункции

Функция  ПолучитьМетодИнфо(тип,ИмяМетода)
	method = Врап.ТипКакОбъект(тип).GetMethod(ИмяМетода);
	
	return method;
	
КонецФункции

Функция  ПолучитьПропертиИнфо(тип,ИмяСвойства)
	свойство = Врап.ТипКакОбъект(тип).GetProperty(ИмяСвойства);
	
	return свойство;
	
КонецФункции

Функция ПолучитьМетодИнфо2Параметра(тип,ИмяМетода)
	
	Для Каждого m in Врап.ТипКакОбъект(тип).GetMethods() Цикл
		
		параметры = m.GetParameters();
		if  (m.Name = ИмяМетода)   
			И (параметры.Length = 2)
			Тогда
			method = m;
			break;
		КонецЕсли
	КонецЦикла;
	
	return method;
	
КонецФункции

Функция Получить_SBAppend()
	
	
	Для Каждого m in Врап.ТипКакОбъект(StringBuilder).GetMethods() Цикл
		
		параметры = m.GetParameters();
		if ( (m.Name = "Append")   
			И (параметры.Length = 1) 
			И (Врап.ТипКакОбъект(параметры.GetValue(0).ParameterType).Equals(String)))   
			Тогда
			возврат  m
		КонецЕсли
	КонецЦикла;
	
	возврат Неопределено
КонецФункции

Процедура AngleSharpFormНажатие(Элемент)
	// Вставить содержимое обработчика.
	
	ПутьКСборке="d:\Vs2015Programs\TestScriptingAPI\TestScriptingAPI\bin\Debug\AngleSharp.dll";
	WebsiteUrl = "http://localhost:54361";
	// Получим используемые типы
        AngleSharp_ConfigurationExtensions = Врап.ПолучитьТип("AngleSharp.ConfigurationExtensions");

	BrowsingContext = Врап.ПолучитьТип("AngleSharp.BrowsingContext");
	BrowsingContextExtensions = Врап.ПолучитьТип("AngleSharp.BrowsingContextExtensions");
	ApiExtensions = Врап.ПолучитьТип("AngleSharp.Extensions.ApiExtensions");
	
	// Получим типы нужных интерфейсов
	IHtmlAnchorElement = Врап.ПолучитьТип("AngleSharp.Dom.Html.IHtmlAnchorElement");
	IHtmlFormElement = Врап.ПолучитьТип("AngleSharp.Dom.Html.IHtmlFormElement");
	IElement=Врап.ПолучитьТип("AngleSharp.Dom.IElement");
	
	// Получим типизированные функции	
	QuerySelector_AnchorElement = ПолучитьДжененрикМетодИнфо(ApiExtensions, "QuerySelector",IHtmlAnchorElement);
	QuerySelector_FormElement =   ПолучитьДжененрикМетодИнфо(ApiExtensions, "QuerySelector",IHtmlFormElement);
	
	ApiExtensions_Navigate=ПолучитьМетодИнфоОдинДженерикТип(ApiExtensions,"Navigate",IHtmlAnchorElement);
	ApiExtensions_Text= ПолучитьМетодИнфоОдинДженерикТип(ApiExtensions,"Text",IElement);
	
	configuration = Configuration.Default;
	
	configuration = AngleSharp_ConfigurationExtensions.WithDefaultLoader(configuration);
	configuration = AngleSharp_ConfigurationExtensions.WithCookies(configuration);
	
	context = BrowsingContext.New(configuration);
	
	// Загрузим начальную страницу
	BrowsingContextExtensions.OpenAsync(context, WebsiteUrl).Wait();
	doc = context.Active;
	
	// Получим ссылку содержащий адрес страницы для авторизации
	//<a class="log-in" href="/Home/LogIn">log in here</a>
	
	HtmlAnchorElement = Врап.MethodInfo_Invoke(QuerySelector_AnchorElement,Неопределено,doc, "a.log-in");
	//  var HtmlAnchorElement = AngleSharp.Extensions.ApiExtensions.QuerySelector<AngleSharp.Dom.Html.IHtmlAnchorElement>(doc, "a.log-in");
	// И перейдем на страницу авторизации
	//  doc = ApiExtensions.Navigate(HtmlAnchorElement).Result;
	
	doc = Врап.MethodInfo_Invoke(ApiExtensions_Navigate,Неопределено,HtmlAnchorElement).Result;
	
	
	//  doc = context.Active;
	
	// Получим форму
	//скрытый элемент для верификации который нужно отправить
	//<input name="__RequestVerificationToken" type="hidden" value="2Y-sFIY9JBZc6wc7antGFsBPG1GoiYCbVDtS0khv3JRkcG8CuN69pS3tAZrSiTevGkBjzpTF9AnuK8tZEUrjqn4qB_lbF4dVxsQBubYZkck1">
	HtmlFormElement = Врап.MethodInfo_Invoke(QuerySelector_FormElement,Неопределено,doc, "form");
	
	//   var HtmlFormElement = AngleSharp.Extensions.ApiExtensions.QuerySelector<AngleSharp.Dom.Html.IHtmlFormElement>(doc, "form");
	
	d = Врап.СоздатьОбъект(Dictionary);
	d.Add("User", "User");
	d.Add("Password", "secret");
	// Авторизуемся установив нужные поля и отправим Post запрос на сервер
	ApiExtensions.Submit(HtmlFormElement, d).Wait();
	
	
	doc = context.Active;
	
	// получим ссылку на искомую страницу
	//<a class="secret-link" href="/Home/Secret">our secret</a>
	HtmlAnchorElement = Врап.MethodInfo_Invoke(QuerySelector_AnchorElement,null, doc, "a.secret-link");
	// HtmlAnchorElement = AngleSharp.Extensions.ApiExtensions.QuerySelector<AngleSharp.Dom.Html.IHtmlAnchorElement>(doc, "a.secret-link");
	
	// Перейдем по ссылке
	// doc = ApiExtensions.Navigate(HtmlAnchorElement).Result;
	doc = Врап.MethodInfo_Invoke(ApiExtensions_Navigate,null,HtmlAnchorElement).Result;
	// В первом селекторе параграфе лежит искомая строка
	//<p>The answer to everything is <span id="secret">42</span>.</p>
	селектор=doc.QuerySelector("p");
	резулт = Врап.MethodInfo_Invoke(ApiExtensions_Text,null,селектор);
	//  резулт =The answer to everything is 42
	Сообщить(резулт);
КонецПроцедуры

Одним из удобных способов это использовать 

https://github.com/dotnet/roslyn

 https://github.com/dotnet/roslyn/wiki/Scripting-API-Samples

 

Для использования Scripting-API создал сборку. Проинсталлировал 

Install-Package Microsoft.CodeAnalysis.Scripting

Создал класс
namespace ScriptApiDlls

{ 
   public class КлассДляВычесленияВыражений 
    { 
      public static  Microsoft.CodeAnalysis.Scripting.ScriptOptions Опции { get { return Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default; } } 
       
        public static object Вычислить(string Код, Microsoft.CodeAnalysis.Scripting.ScriptOptions опции ) 
        { 
            return Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.EvaluateAsync(Код, опции).Result;

        }

    } 
}

 

И теперь можно с удобством использовать код, написанный на C#.

Для использования DLL не из GAC их нужно поместить в домен приложения. В данном случае это каталог программы.

врап=новый COMОбъект("NetObjectToIDispatch45");
	КлассДляВычесленияВыражений=Врап.ПолучитьТипИзСборки("ScriptApiDlls.КлассДляВычесленияВыражений",ПутьКДлл+"ScriptApiDlls.dll");

	Опции=КлассДляВычесленияВыражений.Опции;
	Катаог=Врап.ПолучитьТип("System.AppDomain").CurrentDomain.BaseDirectory;
	ИмяСборкиAngleSharp=Врап.ПолучитьТип("System.IO.Path").Combine(Катаог,"AngleSharp.dll");
	СтрокаКода = "string WebsiteUrl = ""http://localhost:54361"";
	|var configuration = Configuration.Default.WithDefaultLoader().WithCookies();
	|    var context = BrowsingContext.New(configuration);
	|    context.OpenAsync(WebsiteUrl).Wait();
	|   
	|   var elem=context.Active.QuerySelector<IHtmlAnchorElement>(""a.log-in"");
	|   if (elem==null) return context.Active.Body.InnerHtml;
	|   elem.Navigate().Wait();
	|    context.Active.QuerySelector<IHtmlFormElement>(""form"").Submit(new
	|    {
	|        User = ""User"",
	|        Password = ""secret""
	|    }).Wait();
	|context.Active.QuerySelector<IHtmlAnchorElement>(""a.secret-link"").Navigate().Wait();
	|
	|return context.Active.QuerySelector(""p"").Text();
	|";
	
	scr = Опции
	.WithReferences(ИмяСборкиAngleSharp)
	.WithImports("System","AngleSharp","AngleSharp.Dom.Html","AngleSharp.Extensions");
	
	
	резулт = КлассДляВычесленияВыражений.Вычислить(СтрокаКода,scr);
	Сообщить(резулт);

 

А сейчас я расскажу, как можно значительно ускорить процесс использования AngleSharp. Вообще скорость вызовов методов через обертку составляет порядка 20 000 вызовов методов в секунду. Но дело в том, что все классы в библиотеке являются не публичными, передаются только интерфейсы. И вот здесь при передаче ссылок .Net начинает тормозить.  Но решение было найдено через использование типизированных коллекций и использование PropertyInfo

stopWatch = Врап.СоздатьОбъект("System.Diagnostics.Stopwatch");
	
	stopWatch.Start();
	
	Client = Врап.СоздатьОбъект(HttpClient);
	Client.BaseAddress = Врап.СоздатьОбъект("System.Uri","https://en.wikipedia.org");
	res = Client.GetStringAsync("wiki/List_of_The_Big_Bang_Theory_episodes").Result;
	
	parser = Врап.СоздатьОбъект("AngleSharp.Parser.Html.HtmlParser");
	//Just get the DOM representation
	document = parser.Parse(res);
	СелекторСтроки = "tr.vevent";
	Тз=новый ТаблицаЗначений;
	Колонки=Тз.Колонки;
	Колонки.Добавить("НомерСерии");
	Колонки.Добавить("НомерСерииВСезоне");
	Колонки.Добавить("Название");
	Колонки.Добавить("Режиссер");
	Колонки.Добавить("Автор");
	Колонки.Добавить("Дата");
	Колонки.Добавить("Код");
	Колонки.Добавить("Просмотров");
	
	Строки =document.QuerySelectorAll(СелекторСтроки);
	
	stopWatch.Stop();
	Сообщить("Скачка и парсинг");
	ВывестиВремя(stopWatch,истина);
	Dom_INode=Врап.ПолучитьТип("AngleSharp.Dom.INode");
	TextContentСвойство=ПолучитьПропертиИнфо(Dom_INode,"TextContent");
	
	IHtmlTableRowElement=Врап.ПолучитьТип("AngleSharp.Dom.Html.IHtmlTableRowElement");
	ЯчейкиТаблицыСвойство=ПолучитьПропертиИнфо(IHtmlTableRowElement,"Cells");
	
	IEnumerator=Врап.ПолучитьТип("System.Collections.IEnumerator");
	CurrentСвойство=ПолучитьПропертиИнфо(IEnumerator,"Current");
	stopWatch.Restart();
	
	//  Строки=Врап.МассивИзЭнумератора(Строки,IHtmlTableRowElement);//Врап.ПолучитьПеречислитель(строки);
	Строки=Врап.ПолучитьТипизированныйПеречислитель(Строки,IHtmlTableRowElement);	
	
	Для каждого стр из Строки Цикл
		сч=0;
		стрТз=Тз.Добавить();
		Ячейки=ЯчейкиТаблицыСвойство.GetValue(стр);//Ячейки=стр.Cells;
		
		//Ячейки=Врап.МассивИзЭнумератора(Ячейки,Dom_INode);
		Ячейки=Врап.ПолучитьТипизированныйПеречислитель(Ячейки,Dom_INode);
		
		Для каждого Ячейка из Ячейки Цикл
			стрТз[сч]=TextContentСвойство.GetValue(Ячейка);//Ячейка.TextContent;
			
			сч=сч+1;
			Если сч=8 Тогда
				прервать
			КонецЕсли;
		КонецЦикла
	КонецЦикла;
	
	stopWatch.Stop();
	
	
	Сообщить("Время выполнения =");
	ВывестиВремя(stopWatch,истина);
	
	Тз.ВыбратьСтроку();	

Используя MetodInfo, тоже можно ускорить процесс процентов на 20%. 

stopWatch = Врап.СоздатьОбъект("System.Diagnostics.Stopwatch");
	
	КоличествоИтераций=20000;
	stopWatch.Start();
	
	StringBuilder_Append=Получить_SBAppend();
	StringBuilder_ToString=ПолучитьМетодИнфо2Параметра(StringBuilder,"ToString");
	стр="";
	НачВремя=ТекущаяДата();
	stopWatch.Restart();
	SB =  врап.СоздатьОбъект("System.Text.StringBuilder");
	Для сч=1 по КоличествоИтераций Цикл
		//	SB.Append(Строка(сч));
		Врап.MethodInfo_Invoke(StringBuilder_Append,SB,Строка(сч));
		
	КонецЦикла;
	
	stopWatch.Stop();
	
	стр=SB.ToString();
	Сообщить(СтрДлина(стр));
	
	ВывестиВремя(stopWatch,истина);
	
	stopWatch.Restart();
	
	SB2 =  врап.СоздатьОбъект("System.Text.StringBuilder");
	Для сч=0 по SB.Length-1 Цикл
		
		//SB2.Append(SB.ToString(сч,1));
		Врап.MethodInfo_Invoke(StringBuilder_Append,SB2,Врап.MethodInfo_Invoke(StringBuilder_ToString,SB,сч,1));
		
	КонецЦикла;
	stopWatch.Stop();
	
	стр=SB2.ToString();
	Сообщить(СтрДлина(стр));
	
	
	
	
	Сообщить("Время выполнения =");
	ВывестиВремя(stopWatch,истина);
Для получения атрибута нужно применить следующий код
В 
Картинки = doc.QuerySelectorAll("img[src]");

Для каждого стр из Картинки Цикл
 адрес=Врап.ПолучитьИнтерфейс(стр,"IElement").GetAttribute("src");
  
КонецЦикла

 

 Так же приеры использования AngleSharp на .Net Core  есть здесь

Кроссплатформенное использование классов .Net в 1С через Native ВК. Или замена COM на Linux II

и здесь

.Net Core, 1C, динамическая компиляция, Scripting API

Благодарю всех, кто дошел до конца. Надеюсь, мои труды вам пригодятся.

110

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. Serginio 796 11.03.16 11:50 Сейчас в теме
Я уже не буду перегружать статью. Но можно использовать скрипты для заполнения данных 1С
str = "public class ВычислительAngleSharp
    |{
     |public  static void ЗаполнитьТз(dynamic ТЗ)
     |   {
	 |
	 |
     |       var config = Configuration.Default.WithDefaultLoader();
     |       // Устанавливаем адрес страницы сайта
     |       var address = ""https://en.wikipedia.org/wiki/List_of_The_Big_Bang_Theory_episodes"";
     |       // загружаем страницу и разбираем её
     |       var document = BrowsingContext.New(config).OpenAsync(address).Result;
     |       // Используем CSS селектор для получения строк таблицы с классом  и выбрать из этой строки 3 колонку 
     |       var rowSelector = ""tr.vevent"";
     |       var Строки = document.QuerySelectorAll<IHtmlTableRowElement>(rowSelector);
     |       foreach (var str in Строки)
     |       {
     |           dynamic стрТз = ТЗ.Добавить();
     |           var ячейки = str.Cells;
     |           for (int i = 0; i < Math.Min(ячейки.Length, 8); i++)
     |           {
     |
     |               стрТз.Установить(i, ячейки[i].TextContent);
     |
     |           }
     |
     |
     |       }
     |
     |   }
    |}
|
|return  new Action<dynamic>(ВычислительAngleSharp.ЗаполнитьТз);";

            Каталог=Врап.ПолучитьТип("System.AppDomain").CurrentDomain.BaseDirectory;
            КаталогGAC = Path.GetDirectoryName(Врап.ТипКакОбъект(string).Assembly.Location);
			
			ПутьКДлл="d:\Vs2015Programs\ScriptApiDlls\ScriptApiDlls\bin\Debug\";
			КлассДляВычесленияВыражений=Врап.ПолучитьТипИзСборки("ScriptApiDlls.КлассДляВычесленияВыражений",ПутьКДлл+"ScriptApiDlls.dll");
	       
	        Опции=КлассДляВычесленияВыражений.Опции;

              scr = Опции
                .WithReferences(Каталог + "\AngleSharp.dll", КаталогGAC + "\Microsoft.CSharp.dll")
                //  .WithReferences(typeof(Configuration).Assembly)
                .WithImports("System", "AngleSharp", "AngleSharp.Dom.Html", "AngleSharp.Extensions");

               result = КлассДляВычесленияВыражений.Вычислить(str, scr);
			  Тз=новый ТаблицаЗначений;
	Колонки=Тз.Колонки;
	Колонки.Добавить("НомерСерии");
	Колонки.Добавить("НомерСерииВСезоне");
	Колонки.Добавить("Название");
	Колонки.Добавить("Режиссер");
	Колонки.Добавить("Автор");
	Колонки.Добавить("Дата");
	Колонки.Добавить("Код");
	Колонки.Добавить("Просмотров");

	врап.ВыполнитьДелегат(result,Тз);
	
	тз.ВыбратьСтроку();
Показать
2. YPermitin 4966 11.03.16 13:55 Сейчас в теме
(1) классные статьи, тоже интересная.

Но есть парочку НО:
1. Материал подается в неудобочитаемом виде.
2. Мало практических примером, близких к реальности.

ИМХО. Без обид.
Gureev; yarsort; +2 Ответить
3. Serginio 796 11.03.16 14:40 Сейчас в теме
(2) Спасибо. Может подкинешь идею? Могу в свободное время взяться за конкретный пример или кому то помочь с реальной задачей
4. invertercant 22 11.03.16 16:11 Сейчас в теме
(3) я был бы рад увидеть статью про валидаторы данных применительно к 1с, особенно приятно если бы это получилось хорошо. Понимаю что тема большая, но хоть что то. Вот например по этой тематике https://habrahabr.ru/post/246521/
5. Serginio 796 11.03.16 16:21 Сейчас в теме
(4) Да уж. Можно смотреть на валидаторы внутри ASP.Net MVC. Там генерятся валидаторы как на JavaScript так и на уровне HTML5
http://stephenwalther.com/archive/2012/03/13/html5-form-validation
6. invertercant 22 11.03.16 16:56 Сейчас в теме
(5) У тебя по ссылке валидация форм, хотя хотелось бы иметь валидацию произвольных данных. На входе - произвольный набор проверяемых данных и правила которым он должен удовлетворять. На выходе - ошибки, если есть. Если ошибок нет - валидация прошла успешно. Например, ты грузишь что то из какого нибудь excel или внешней базы и надо чтобы данные удовлетворяли определенным условиям. Часто фарш в данных обнаруживается значительно позднее чем мог бы.
14. YPermitin 4966 14.03.16 08:58 Сейчас в теме
(3) можно написать обработку, которая сжимает или приводит к одному виду изображения в базе с помощью средств .NET платформы, да еще и Parallel прикрутить для ускорения.
Еще было бы интересно рассказать про стандартные возможности .NET'а слежения за изменением в каталоге, передача файлов по сети с помощью фоновой интеллектуальной службы BITS (Windows).

Может об этом уже писали конечно, не искал специально.
15. Serginio 796 14.03.16 09:51 Сейчас в теме
(14) Большое спасибо за совет.
.NET(C#) для 1С. Динамическая компиляция класса обертки для использования .Net событий в 1С через ДобавитьОбработчик или ОбработкаВнешнегоСобытия
Там есть подписка на события System.IO.FileSystemWatcher

Насчет картинок была статья Elisy Обработка изображений 1С средствами .Net framework
Я на мисте предлагал http://www.forum.mista.ru/topic.php?id=758131&page=3#229
Но как то мало это народ интересует.
Нужны какие то простые, но понятные примеры типа Строка в дату. Универсальное решение. Применение NetObjetToIDispatch45
http://www.forum.mista.ru/topic.php?id=763810&page=1

Например больше всего популярностью пользуется Использование классов .Net в 1С для новичков
Главное заинтересовать, а там дальше пойдет.
dima.jung; +1 Ответить
30. Denanhel 05.10.18 19:48 Сейчас в теме
(15) Пилил сжатие изображений.

ИмяВходногоФайлаКартинки - путь к файлу картинки
		
ИмяВыходногоФайлаКартинки = ПолучитьимяВременногоФайла(".jpg")

Врап = новый COMОбъект("NetObjectToIDispatch45");  		
			
Picture = Врап.СоздатьОбъект("System.Drawing.Bitmap", ИмяВходногоФайлаКартинки);
			
Множитель = Макс(Число(Picture.Height), Число(Picture.Width)) / 500;

Если Множитель >= 1 Тогда
	nPicture = Врап.СоздатьОбъект("System.Drawing.Bitmap", Picture, Цел(Picture.Width/Множитель), 
        Цел(Picture.Height/Множитель));
        Picture.Dispose();
        nPicture.Save(ИмяВыходногоФайлаКартинки); 
        nPicture.Dispose();
Показать

КонецЕсли;

Режет картику до размера 500 пикселей на сколько-то там.... Ну исходя из начального размера. Если размер меньше 500 пикселей то оставляет как есть, жмет неплохо, качество не теряется, быстро и сердито, можно красивее, но нужно было сделать что-то быстро, а потом оказалась и так неплохо.
20. Serginio 796 24.03.16 15:16 Сейчас в теме
В составе AngleSharp.Scripting для парсинга сайтов с использованием JS
https://github.com/AngleSharp/AngleSharp/wiki/Examples

Есть парсер
https://github.com/sebastienros/jint

Вот пример использования

Engine=врап.ПолучитьТипИзСборки("Jint.Engine","d:\Vs2015Programs\WpfApplication1\WpfApplication1\bin\Debug\Jint.dll"); 



    JsValue=врап.ПолучитьТип("Jint.Native.JsValue");
      jint =  Врап.СоздатьОбъект (Engine);

            html = "
            |var o = { };
            |o.Foo = 'bar';
            |o.Baz = 42.0001;
            |o.Blah = o.Foo + o.Baz;
            |o.B64='YWRtaW5AbG9jYWxob3N0OnNlY3JldAo==';
            |o.Int =5;
            |if (o.Blah != 'bar42.0001') throw TypeError;
            |
            |function fib(n){
            |    if (n < 2)
            |    {
            |        return n;
            |    }
            |
            |    return fib(n - 1) + fib(n - 2);
            |}
            |
            |if (fib(3) != 2) throw TypeError;
            |";

            jint.Execute(html);
            o = jint.GetValue("o").ToObject();

            Baz = o.Baz;
            Сообщить(Baz);
            Сообщить(o.Blah);
            Сообщить(o.Int);            
            BitConverter=Врап.ПолучитьТип("System.BitConverter");
            Convert  =Врап.ПолучитьТип("System.Convert");
            data = Convert.FromBase64String(o.B64);
                        Сообщить(BitConverter.ToString(data));
          // int ii = o.Int;


            fib = jint.GetValue("fib");
            
            double5=Врап.ChangeType("System.Double",5);
            double5=Врап.СоздатьОбъект(JsValue,double5);
            Фиб5=врап.ВыполнитьМетод(fib,"Invoke",double5).AsNumber();

        //    Фиб5=fib.Invoke(double5).AsNumber();

            Сообщить(Фиб5);
Показать
16. Serginio 796 15.03.16 10:36 Сейчас в теме
Еще один пример парсинга


Client = Врап.СоздатьОбъект(HttpClient);
	Client.BaseAddress = Врап.СоздатьОбъект("System.Uri","http://www.5lb.ru/catalog/");
	Стр="/cgi-bin/mp/page.pl?id=32&m=docs&producer_id=0&price_min=220&price_max=8520&sele­ct_rating=0&unit_6=1&min_6=114&max_6=1588&unit_4=1&min_4=20&­max_4=25&unit_5=1&min_5=30&max_5=500&unit_7=1&min_7=12&max_7­=40&unit_3=1&min_3=60&max_3=600&unit_1=1&min_1=12&max_1=12&u­nit_2=1&min_2=500&max_2=1000";
		
	
// Тест строки с параметрами из фиддлера	
	res = Client.GetStringAsync(стр).Result;
	
	// Посмотрим результат
	// Можно посмотреть страницу используя например
	//http://filyanin.ru/8-vizualnyy-HTML-onlayn-redaktor.html
	Текст=Новый ТекстовыйДокумент;
	Текст.УстановитьТекст(res);
	Текст.Показать();

	
	res = Client.GetStringAsync("bcaa.html").Result;
	document = parser.Parse(res);

		
	Форма=document.QuerySelectorAll("form").get_Item(1);
	ссылка=	СокрЛП(Форма.Action);
		

	структура=новый структура;
	Для каждого Элемент Из Форма.QuerySelectorAll("input")  Цикл
		Элем=Врап.ПолучитьИнтерфейс(Элемент,"IHtmlInputElement");
		//Нужны только Input элементы
		//Выберем все элементы Input
		// и запишем их имена и значения
		
		Если ПустаяСтрока(Элем.Name) Тогда
		   Продолжить;
	    КонецЕсли;
	
		Если Элем<> Неопределено Тогда
			Сообщить(Элем.Name+"="+Элем.Value);

			структура.Вставить(Элем.Name,Элем.Value);
			
			
		КонецЕсли; 
		
		
	КонецЦикла; 		

	
	// Можно изменить значение
	//структура.price_max="3000";
	структура.Вставить("producer_id","0");
	структура.Вставить("select_rating","0");
	сб=Врап.СоздатьОбъект(StringBuilder,ссылка+"?");
	//var uri = new Uri(builder.ToString(), dontEscape: true);
	
	// Создадим строку запроса. Для метода Get
	// так как Форма.Method=""
	Для каждого стр Из структура  Цикл
		
		
		сб.AppendFormat("{0}={1}&",HttpUtility.UrlPathEncode(стр.Ключ),HttpUtility.UrlPathEncode(стр.Значение),0);
		
		
	КонецЦикла; 

	
	стр=сб.ToString(0,сб.Length-1); 
	Сообщить(стр);
	//Сделаем запрос по относительному пути
	//Так как основной путь уже прописан в BaseAddress
	res = Client.GetStringAsync(стр).Result;
	
	// Посмотрим результат
	// Можно посмотреть страницу используя например
	//http://filyanin.ru/8-vizualnyy-HTML-onlayn-redaktor.html
	Текст=Новый ТекстовыйДокумент;
	Текст.УстановитьТекст(res);
	Текст.Показать();
	
	document = parser.Parse(res);
Показать
8. invertercant 22 11.03.16 17:15 Сейчас в теме
(7) Это была идея для статьи чтобы не придумывать велосипед, а взять готовый на NET, если такой существует.
9. Serginio 796 11.03.16 17:19 Сейчас в теме
(8) Они существуют. Только не универсальные. XML, HTML, C# итд.
10. Serginio 796 11.03.16 17:29 Сейчас в теме
Что касается LIVR то прочтя https://github.com/koorchik/LIVR вроде как на .Net нет библиотеки
11. Serginio 796 11.03.16 20:15 Сейчас в теме
Вот пример парсинга мисты

 handler = врап.СоздатьОбъект(HttpClientHandler);

    

    cookieContainer = Врап.СоздатьОбъект("System.Net.CookieContainer");

  

   handler.AutomaticDecompression=Врап.OR(DecompressionMethods.GZip,DecompressionMethods.Deflate) ;

      handler.CookieContainer=cookieContainer;

      cookieContainer.Add(Врап.СоздатьОбъект("System.Net.Cookie","__DDOS_COOKIE", "6c950441aeaf13f026a3aa8c0fee6df2", "/", "http://www.forum.mista.ru";));

   handler.UseCookies=истина;

//Pragma: no-cache

   Клиент = Врап.СоздатьОбъект(HttpClient,handler);

   DefaultRequestHeaders=Клиент.DefaultRequestHeaders;

   

   DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,*/*");



   WebsiteUrl = "http://www.forum.mista.ru/";

   Клиент.BaseAddress = Врап.СоздатьОбъект("System.Uri",WebsiteUrl);



            

    res = Клиент.GetStringAsync("index.php").Result;

    document = parser.Parse(res);

    

    селектор="table#tm td.ct";

    



    Ячейки= document.QuerySelectorall(селектор);

    

    Для каждого Ячейка Из Ячейки Цикл

        

        Аннотации=Ячейка.QuerySelectorall("a");

    Сообщить("=============================");    

Для каждого Аннотация Из Аннотации Цикл



Сообщить(Аннотация.TextContent+"="+Аннотация.PathName+Аннотация.Search);    



КонецЦикла; 

        

    

    КонецЦикла; 

Врап.ЗакрытьРесурс(HttpClient);
Показать
12. Serginio 796 12.03.16 10:44 Сейчас в теме
Обратите внимание
Аннотация= document.QuerySelector("a.log-in");
    //Полный относительный путь Аннотация.PathName+Аннотация.Search
    // Но в данном случае Аннотация.Search просто нет
    // Если использовать BrowsingContext то полный путь содержится в Href

    res= Клиент.GetStringAsync(Аннотация.PathName).Result;
13. Serginio 796 13.03.16 14:28 Сейчас в теме
Один из основных интерфейсов

 [DomName("Node")]
    public interface INode : IEventTarget, IMarkupFormattable
    {
        /// <summary>
        /// Gets a string representing the base URL. 
        /// </summary>
        [DomName("baseURI")]
        String BaseUri { get; }

        /// <summary>
        /// Gets the base url.
        /// </summary>
        Url BaseUrl { get; }

        /// <summary>
        /// Gets a string containing the name of the Node. The structure of the
        /// name will differ with the name type. 
        /// </summary>
        [DomName("nodeName")]
        String NodeName { get; }

        /// <summary>
        /// Gets a live NodeList containing all the children of this node.
        /// Being live means that if the children of the node change, the
        /// NodeList object is automatically upd ated.
        /// </summary>
        [DomName("childNodes")]
        INodeList ChildNodes { get; }

        /// <summary>
        /// Clones the node, and optionally, all of its contents.
        /// By default, it clones the content of the node.
        /// </summary>
        /// <param name="deep">
        /// Optionally: Sets if all of the content should be cloned as well.
        /// </param>
        /// <returns>The cloned node.</returns>
        [DomName("cloneNode")]
        INode Clone(Boolean deep = true);

        /// <summary>
        /// Determines if two nodes are equal.
        /// </summary>
        /// <param name="otherNode">
        /// The node to be compared to the node that is executing the method.
        /// </param>
        /// <returns>
        /// True if the node specified in the otherNode parameter is equal to
        /// the current node.
        /// </returns>
        [DomName("isEqualNode")]
        Boolean Equals(INode otherNode);

        /// <summary>
        /// Compares the position of two nodes in a document.
        /// </summary>
        /// <param name="otherNode">
        /// The node to be compared to the reference node, which is the node
        /// executing the method.
        /// </param>
        /// <returns>The relation between the two nodes.</returns>
        [DomName("compareDocumentPosition")]
        DocumentPositions CompareDocumentPosition(INode otherNode);

        /// <summary>
        /// Cleans up all the text nodes under this element, i.e. merges
        /// adjacent and removes empty text nodes.
        /// </summary>
        [DomName("normalize")]
        void Normalize();

        /// <summary>
        /// Gets the Document that this node belongs to. If no document is
        /// associated with it, returns null.
        /// </summary>
        [DomName("ownerDocument")]
        IDocument Owner { get; }

        /// <summary>
        /// Gets an Element that is the parent of this node. If the node has no
        /// parent, or if that parent is not an Element, this property returns
        /// null.
        /// </summary>
        [DomName("parentElement")]
        IElement ParentElement { get; }

        /// <summary>
        /// Gets a node that is the parent of this node. If there is no such
        /// node, like if this node is the top of the tree or if doesn't
        /// participate in a tree, this property returns null.
        /// </summary>
        [DomName("parentNode")]
        INode Parent { get; }

        /// <summary>
        /// Returns true if other is an inclusive descendant of the context
        /// object, and false otherwise (including when other is null).
        /// </summary>
        /// <param name="otherNode">The Node to check the childs for.</param>
        /// <returns>
        /// True if the given node is contained within this Node, otherwise
        /// false.
        /// </returns>
        [DomName("contains")]
        Boolean Contains(INode otherNode);

        /// <summary>
        /// Gets a Node representing the first direct child node of the node,
        /// or null if the node has no child.
        /// </summary>
        [DomName("firstChild")]
        INode FirstChild { get; }

        /// <summary>
        /// Gets a node representing the last direct child node of the node,
        /// or null if the node has no child.
        /// </summary>
        [DomName("lastChild")]
        INode LastChild { get; }

        /// <summary>
        /// Gets a Node representing the next node in the tree, or null if
        /// there isn't such node.
        /// </summary>
        [DomName("nextSibling")]
        INode NextSibling { get; }

        /// <summary>
        /// Gets a Node representing the previous node in the tree, or null if
        /// there isn't such node.
        /// </summary>
        [DomName("previousSibling")]
        INode PreviousSibling { get; }

        /// <summary>
        /// Indicates whether or not a namespace is the default namespace for a
        /// document.
        /// </summary>
        /// <param name="namespaceUri">
        /// The namespace to be compared to the default namespace.
        /// </param>
        /// <returns>
        /// True if the given namespace URI is the default for the current
        /// document.
        /// </returns>
        [DomName("isDefaultNamespace")]
        Boolean IsDefaultNamespace(String namespaceUri);

        /// <summary>
        /// Gets the Uniform Resource Identifier (URI) of the namespace
        /// associated with a namespace prefix, if any.
        /// </summary>
        /// <param name="prefix">The namespace prefix.</param>
        /// <returns>The URI of the namespace.</returns>
        [DomName("lookupNamespaceURI")]
        String LookupNamespaceUri(String prefix);

        /// <summary>
        /// Gets the namespace prefix associated with a Uniform
        /// Resource Identifier (URI), if any.
        /// </summary>
        /// <param name="namespaceUri">The URI.</param>
        /// <returns>The namespace prefix associated with the URI.</returns>
        [DomName("lookupPrefix")]
        String LookupPrefix(String namespaceUri);

        /// <summary>
        /// Gets an unsigned short representing the type of the node. 
        /// </summary>
        [DomName("nodeType")]
        NodeType NodeType { get; }

        /// <summary>
        /// Gets or sets a string representing the value of an object. For most
        /// node types, this returns null and any set operation is ignored.
        /// </summary>
        [DomName("nodeValue")]
        String NodeValue { get; set; }

        /// <summary>
        /// Gets or sets the textual content of an element and all its
        /// descendants.
        /// </summary>
        [DomName("textContent")]
        String TextContent { get; se t; }

        /// <summary>
        /// Gets an indicator if the element has any child nodes, or not.
        /// </summary>
        [DomName("hasChildNodes")]
        Boolean HasChildNodes { get; }

        /// <summary>
        /// Inserts a node as the last child node of this element.
        /// </summary>
        /// <param name="child">The node to be appended.</param>
        /// <returns>The appended Node.</returns>
        [DomName("appendChild")]
        INode AppendChild(INode child);

        /// <summary>
        /// Inserts the newElement immediately before the referenceElement.
        /// </summary>
        /// <param name="newElement">The node to be inserted.</param>
        /// <param name="referenceElement">
        /// The existing child element that will succeed the new element.
        /// </param>
        /// <returns>The inserted node.</returns>
        [DomName("insertBefore")]
        INode InsertBefore(INode newElement, INode referenceElement);

        /// <summary>
        /// Removes a child node from the current element, which must be a
        /// child of the current node.
        /// </summary>
        /// <param name="child">The child to be removed.</param>
        /// <returns>The removed node.</returns>
        [DomName("removeChild")]
        INode RemoveChild(INode child);

        /// <summary>
        /// Replaces one child node of the current one with the second one
        /// given in the parameters.
        /// </summary>
        /// <param name="newChild">The child to be inserted.</param>
        /// <param name="oldChild">The child to be removed.</param>
        /// <returns>The old node, if any.</returns>
        [DomName("replaceChild")]
        INode ReplaceChild(INode newChild, INode oldChild);
    }
Показать
17. Гость 18.03.16 15:55
Подскажите, пожалуйста, где взять файл AngleSharp.dll?
18. Serginio 796 18.03.16 15:57 Сейчас в теме
(17) http://files.rsdn.ru/19608/AndleSharpScriptDlls.zip

Но за версиями лучше следить здесь https://www.nuget.org/packages/AngleSharp/
https://anglesharp.github.io/
Кстати новая версия вышла. Проверю. Обновил
19. Гость 21.03.16 12:51
Спасибо! А то скачал сборку с Гитхаба, а как ее использовать не понял..
21. Serginio 796 24.03.16 15:17 Сейчас в теме
Можно передавать свои объекты и и использовать их при выполнении скриптов . Пример на C#




html = @"
var document = { };
document.cookie = '__DDOS_COOKIE =6c950441aeaf13f026a3aa8c0fee6df2; max-age=604800; path=/';
          ";

            jint.Execute(html);
            dynamic document = jint.GetValue("document").ToObject();
            textBox.AppendText(document.cookie.ToString() + Environment.NewLine);

            html = @"document.cookie = '__DDOS_COOKIE =6c950441aeaf13f026a3aa8c0fee6df2; max-age=604800; path=/';
            var nc = function() {
                return
document.cookie.indexOf('__DDOS_COOKIE=6c950441aeaf13f026a3aa8c0fee6df2') == -1;
            };
            var w = function() { document.body.innerHTML = document.getElementsByTagName('noscript')[0].textContent; };
            if (!window.opera)
            {
                if (!nc()) { window.location.reload(true); }
                var r = function() { if (nc()) w(); };
            }
            else {
                var r = function() {
                    if (!nc()) { window.location.reload(true); }
                    else { w(); }
                }
            }";

            dynamic document1 = new ExpandoObject();
            document1.cookie = "";
            document1.body= new ExpandoObject();
            dynamic window= new ExpandoObject();
            window.opera = false;
            window.location = new ExpandoObject();
            window.location.reload = (Action<bool>)(® => { });

            jint.SetValue("document", document1);
            jint.SetValue("window", window);

            jint.Execute(html);
           
            textBox.AppendText(document1.cookie.ToString() + Environment.NewLine);
Показать
22. Serginio 796 13.04.16 09:57 Сейчас в теме
Проверил работают такие конструкции поиска

Поиск div с id начинающихся на "row"
СелекторСтроки = "div[id^=row]";


Найти аннотацию с классом pagenav и содеращую текст 'Вперёд'
a.pagenav:contains('Вперёд')
23. Serginio 796 26.04.16 10:17 Сейчас в теме
Я бы еще добавил Silenium прежде всего как построитель DOM в заскриптованных таблицах http://www.seleniumhq.org/docs/05_selenium_rc.jsp#c
http://scraping.pro/example-of-scraping-with-selenium-webdriver-in-csharp/

Для того что бы добраться до сформированного DOM можно использовать вместо PageSource
вычисляемый скрипт

http://stackoverflow.com/questions/26584215/selenium-page-source-does-not-return-modified-dom-tree

var pageSource = (string)driver.ExecuteScript("return document.body.outerHTML");
27. quick 572 23.05.17 23:04 Сейчас в теме
(23) Сергей дело говорит, selenium часто спасает. Правда я его юзаю через python, но какая разница.
Никогда не мог понять зачем делать парсер в 1С, если можно на том же .NET написать нормальный парсер и юзать его через тот же SOAP как веб сервис. А если потребуется парсить в несколько потоков или т.д.? Для чего жопаболь с 1С-языком?
31. Denanhel 05.10.18 19:57 Сейчас в теме
(23) Может кому будет полезным.


Процедура GZIPРаспаковать(вхФайл, исхФайл, МассивОшибок) Экспорт
	
	Попытка
		Врап = новый COMОбъект("NetObjectToIDispatch45");	
		MemoryStream = Врап.ПолучитьТип("System.IO.MemoryStream");
	    UTF8 = Врап.ПолучитьТип("System.Text.Encoding").UTF8;
	    CompressionMode = Врап.ПолучитьТип("System.IO.Compression.CompressionMode");
		FileMode = Врап.ПолучитьТип("System.IO.FileMode"); 			
		
		ПотокСжатыхДанных = Врап.СоздатьОбъект("System.IO.FileStream", вхФайл, FileMode.OpenOrCreate);
		GZipПоток = Врап.СоздатьОбъект("System.IO.Compression.GZipStream", ПотокСжатыхДанных, CompressionMode.Decompress);
		ПотокРазжатыхДанных = Врап.СоздатьОбъект("System.IO.FileStream", исхФайл, FileMode.OpenOrCreate);
		GZipПоток.CopyTo(ПотокРазжатыхДанных);     		
			
		ПотокСжатыхДанных.Close();
		GZipПоток.Close(); 
		ПотокРазжатыхДанных.Close();
	Исключение
		МассивОшибок.Добавить("Не удалось распаковать данные" + " " + ОписаниеОшибки()); 
		Возврат;
	КонецПопытки;
КонецПроцедуры

Показать
24. Serginio 796 01.06.16 21:22 Сейчас в теме
Для получения атрибута нужно применить следующий код

Картинки = doc.QuerySelectorAll("img[src]");

Для каждого стр из Картинки Цикл
	адрес=Врап.ПолучитьИнтерфейс(стр,"IElement").GetAttribute("src");
	
КонецЦикла
25. user650124_dao-piglet 09.12.16 18:43 Сейчас в теме
Сергей, подскажите плиз, что не так в этом коде?
Объекты HttpClient и HttpRequestMessage создаются.
А дальше нужно добавить к запросу Method и RequestUri - это не получается.
(В C# аналогичный код работает)

ХТТПЗапрос.RequestUri = Врап.СоздатьОбъект("System.Uri", адрес);
HttpMethod = Врап.ПолучитьТипИзСборки("System.Net.Http.HttpMethod", "System.Net.Http.dll");
ХТТПЗапрос.Method = HttpMethod.Get;

И в 1-й и в 2-й строках одинаковая ошибка:
Произошла исключительная ситуация (mscorlib): Exception has been thrown by the target of an invocation.

Получение System.Uri видел у Вас здесь и в других публикациях. HttpMethod попробовал методом тыка.
26. Serginio 796 10.12.16 18:22 Сейчас в теме
А зачем для Get нужен какой то метод. Используй нужные методы с Get
Вот здесь куча примеров
.Net в 1С. Асинхронные HTTP запросы, отправка Post нескольких файлов multipart/form-data, сжатие трафика с использованием gzip, deflate, удобный парсинг сайтов и т.д.

Используй HTTPClient . он более продвинутый. У меня все примеры с ним.
29. s_vidyakin 06.08.18 13:40 Сейчас в теме
А как тестировать и отлаживать парсинг? Компилить каждый раз прогу на C# или дергать весь сайт заново из 1С?
Не надо извращений со скрещиванием C# и 1С. Берете python и пишете на BeautyfulSoup парсинг в реальном времени в консольке.
Изучается за час-два, получаете результат в JSON и передаете в 1С.

Можно и прямо из 1С запускать готовые py-скрипты, даже хранить их в базе, а не зашивать в хардкоде алгоритмы.

Уже не один год вижу статьи про .NET+1C, такое ощущение что автору в какой то глубинке нечем заняться и он упорно шлифует "свою прелесть"
albert.goncharov; +1 Ответить
32. albert.goncharov 83 03.12.18 23:31 Сейчас в теме
А есть ли какой-то способ вызывать конструкции вида =>
?
    //Do something with LINQ
    var blueListItemsLinq = document.All.Where(m => m.LocalName == "li" && m.ClassList.Contains("blue"));
33. albert.goncharov 83 21.07.19 03:08 Сейчас в теме
Потребовалось находить дженерик-функцию SubmitAsync, у которой больше 2-х параметров, которая видимо в современных редакциях AngleSharp превратилась в дженерик.
Вот как она выглядит в файле AngleSharp.xml:
AngleSharp.Extensions.ApiExtensions.SubmitAsync(AngleSharp.Dom.Html.IHtmlFormElement,System.Collections.Generic.IDictionary{System.String,System.String},System.Boolean)

Если обратить внимание на её описание - то можно заметить что ниже по тексту идут ИМЕНОВАННЫЕ параметры, с которыми она вызывается.
// Возвращает метод дженерик-фунции
//
// Параметры:
//	Врап		- COMОбъект("NetObjectToIDispatch45")	- первый параметр при работе с библиотеками .NET из 1С
//	тип			- COMОбъект								- тип того объекта, который на C# пишется перед точкой при вызове дженерик-метода
//	ИмяМетода	- Строка								- собственно тот дженерик-метод, который мы ищем
//	имяПараметра1...имяПараметра9						- подсмотренные в AngleSharp.xml названия параметров дженерик-метода, по которым мы можем отличить его от других похожих
//
// Возвращаемое значение:
//	COMОбъект		- который потом может приниматься в качестве параметра при вызове Врап.MethodInfo_Invoke(COMОбъект, null, Параметр1, Параметр2, ...)
//	Неопределено	- в случае, когда метод найти не удалось
//
Функция ПолучитьМетодИнфоМногоПараметров(Врап, тип, ИмяМетода, имяПараметра1 = Неопределено, имяПараметра2 = Неопределено, имяПараметра3 = Неопределено,
																имяПараметра4 = Неопределено, имяПараметра5 = Неопределено, имяПараметра6 = Неопределено,
																имяПараметра7 = Неопределено, имяПараметра8 = Неопределено, имяПараметра9 = Неопределено) Экспорт
	
	method = Неопределено;
	
	КоличествоПараметров = ?(имяПараметра1 = Неопределено, 0,
		?(имяПараметра2 = Неопределено, 1,
		?(имяПараметра3 = Неопределено, 2,
		?(имяПараметра4 = Неопределено, 3,
		?(имяПараметра5 = Неопределено, 4,
		?(имяПараметра6 = Неопределено, 5,
		?(имяПараметра7 = Неопределено, 6,
		?(имяПараметра8 = Неопределено, 7,
		?(имяПараметра9 = Неопределено, 8, 
	9)))))))));
	
	Для каждого m in Врап.ТипКакОбъект(тип).GetMethods() Цикл
        
        параметры = m.GetParameters();
		
		if (m.Name = ИмяМетода) И (параметры.Length = КоличествоПараметров) Тогда
			
			КоличествоСовпавших = 0;
			
			Для каждого параметр Из параметры Цикл
			
				Если (параметр.Name = имяПараметра1)
						Или (параметр.Name = имяПараметра2) 
						Или (параметр.Name = имяПараметра3) 
						Или (параметр.Name = имяПараметра4) 
						Или (параметр.Name = имяПараметра5) 
						Или (параметр.Name = имяПараметра6) 
						Или (параметр.Name = имяПараметра7) 
						Или (параметр.Name = имяПараметра8) 
						Или (параметр.Name = имяПараметра9) // поскольку когда имяПараметра9 = Неопределено - то совпасть они не могут
				Тогда
						
					КоличествоСовпавших = КоличествоСовпавших + 1;
					
				КонецЕсли;
			
			КонецЦикла;
			
			Если КоличествоСовпавших = КоличествоПараметров Тогда
				method = m;
				Прервать;
			КонецЕсли;
			
		КонецЕсли;
		
    КонецЦикла;
    
    return method;
    
КонецФункции // ПолучитьМетодИнфоМногоПараметров()
Показать
Оставьте свое сообщение

См. также

Самый примитивный HTTP-сервис в мире 162

Статья Программист Нет файла v8 Бесплатно (free) WEB

Пошаговый пример создания простейшего HTTP-сервиса, который генерирует HTML-страницу для поиска товара, а также реализует асинхронное получение данных из базы.

12.09.2019    5776    YPermitin    25       

Агрегатные функции СКД, о которых мало кто знает 315

Статья Программист Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования

Пользуетесь ли Вы всеми возможными агрегатными функциями, которые предоставляет система компоновки данных? Если Вы используете только: СУММА, КОЛИЧЕСТВО, МИНИМУМ, МАКСИМУМ, СРЕДНЕЕ, то эта статья для Вас.

05.09.2019    9323    ids79    42       

Отслеживание выполнения фонового задания 133

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Универсальные функции Разработка

Запуск фонового задания из модуля внешней обработки. Отслеживание выполнения задания в виде прогресса, расположенного на форме.

17.08.2019    7804    ids79    14       

Функции СКД: ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив 239

Статья Программист Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования

Подробное описание и использование внутренних функций системы компоновки данных: Вычислить, ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив, ВычислитьВыражениеСГруппировкойТаблицаЗначений.

08.08.2019    9680    ids79    22       

СКД - наборы данных и связи между ними, создание собственной иерархии, вложенные отчеты 125

Статья Программист Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования Разработка

Набор данных объект. Использование в схеме компоновки нескольких наборов данных. Различные варианты связи наборов: объединение, соединение. Использование иерархии в отчетах на СКД. Создание собственной иерархии, иерархия детальных записей. Использование вложенных схем в отчетах на СКД.

26.07.2019    8755    ids79    6       

СКД - использование расширений языка запросов, секция ХАРАКТЕРИСТИКИ 134

Статья Программист Нет файла v8 v8::СКД Бесплатно (free) Инструментарий разработчика Практика программирования Разработка

Автоматическое и не автоматическое заполнение полей компоновки данных. Использование расширений языка запросов для СКД «{…}», секция ВЫБРАТЬ, секция ГДЕ, параметры виртуальных таблиц. Автоматизированное использование дополнительных данных в запросе: секция ХАРАКТЕРИСТИКИ.

17.07.2019    8263    ids79    24       

"Меньше копипаста!", или как Вася универсальную процедуру писал 170

Статья Программист Стажер Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования Разработка

Программист Вася разбирает подход создания универсальных методов на примере программного вывода СКД.

04.07.2019    6086    SeiOkami    48       

Создание отчетов с помощью СКД - основные понятия и элементы 188

Статья Программист Нет файла v8 v8::СКД Бесплатно (free) Практика программирования Математика и алгоритмы

Основные принципы работы СКД. Понятия схемы компоновки и макета компоновки. Описание основных элементов схемы компоновки: наборы данных, поля, вычисляемые поля, ресурсы, параметры.

25.06.2019    16862    ids79    16       

Многопоточное ускорение однопользовательских нагрузок в 1С + Microsoft SQL Server 2017 174

Статья Программист Нет файла v8 v8::Запросы Бесплатно (free) Практика программирования Разработка

Взаимодействие с Microsoft SQL Server нередко вызывает трудности у 1С-ников, а потому интересны любые моменты, связанные с его использованием. О своем опыте работы с новым SQL Server 2017 участникам конференции Infostart-2018 рассказал директор ООО «Аналитика софт» Дмитрий Дудин.

11.06.2019    11250    dmurk    134       

Регистры накопления. Структура хранения в базе данных 172

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Разработка

Структура хранения регистров накопления в базе данных для платформы 1С:Предприятие 8.x. Первая часть в серии публикаций.

16.05.2019    16852    YPermitin    27       

Выполнение внешней обработки в фоновом задании 147

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Разработка

Подробное описание подхода к созданию длительной операции на основе внешней обработки. Реализация протестирована на 1С 8.3.12.1714 (x64).

11.05.2019    9498    Eret1k    22       

Выгрузка документа по условию 5

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Разработка

Что делать, если документы нужно выгружать не все подряд, а по какому-то фильтру: статусу, дате, набору условий... А что если он соответствовал этим условиям, а потом перестал? А если потом опять начал? Такие ситуации заставили попотеть не одного программиста.

25.04.2019    4648    m-rv    2       

HTML-клиент у конфигурации 1С 137

Статья Программист Нет файла v8 Бесплатно (free) WEB

Приветствую. В этой публикации опишу свой опыт создания html-клиента для конфигурации 1С с помощью http-сервисов. HTML-клиент в этом случае - это frontend (html + css+ js), который генерирует и выдает пользователю конфигурация + backend, который тоже реализован в этой же конфигурации.

17.04.2019    10812    Smaylukk    119       

Как прикрутить ГУИД к регистру сведений 23

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Перенос данных из 1C8 в 1C8 Разработка

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

16.04.2019    7161    m-rv    16       

О расширениях замолвите слово... 193

Статья Программист Стажер Нет файла v8 Бесплатно (free) Практика программирования Разработка

О чём стоит задуматься при принятии решения о создании расширения конфигурации…

07.04.2019    16038    ellavs    122       

Git-репозитории для 1С-кода (опыт использования при небольших проектах) 199

Статья Программист Стажер Нет файла v8 Windows Бесплатно (free) Практика программирования Разработка

Инструкции по взаимодействию с Git-репозиторием, которые писались для тех наших программистов, которые вообще никогда не работали с Git (руководства в духе "Как получить код из git-репозитория?", "Как отправить код в git-репозиторий")...

28.03.2019    12478    ellavs    83       

Трюки с внешними источниками данных 164

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Разработка

Некоторые трюки для преодоления ограничений внешних источников данных.

14.03.2019    12575    YPermitin    52       

Возможности типовых шаблонов ограничения доступа на уровне записей (RLS) 162

Статья Программист Нет файла v8 v8::Права Бесплатно (free) Практика программирования БСП (Библиотека стандартных подсистем) Роли и права

Краткий обзор применения типовых шаблонов ограничения доступа на уровне записей в конфигурациях, созданных на базе БСП: #ПоЗначениям, #ПоНаборамЗначений, #ПоЗначениямРасширенный, #ПоЗначениямИНаборамРасширенный

03.02.2019    15056    ids79    9       

EnterpriseData – часть 2. Процесс выгрузки данных 126

Статья Программист Нет файла v8 v8::УФ Россия Бесплатно (free) Практика программирования Обмен через XML

Основные этапы выгрузки данных через ED, обработчики событий выгрузки, правила обработки данных, правила конвертации объектов, конвертация свойств первого и второго этапов, процедуры БСП, используемые при выгрузке данных, структура «КомпонентыОбмена».

26.12.2018    12462    ids79    27       

Новый подход к обмену данными EnterpriseData 202

Статья Программист Нет файла v8 v8::УФ Россия Бесплатно (free) Практика программирования Обмен через XML

Хочу предложить Вашему вниманию цикл статей, посвященных обмену данными через универсальный формат (EnterpriseData или ED).

14.12.2018    20970    ids79    72       

Программное заполнение пользовательских параметров и отборов СКД 135

Статья Программист Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования

Публикация представляет из себя краткие примеры того, как можно заполнять параметры СКД программно так, чтобы все параметры и отборы были доступны в быстрых настройках и в обычных (типовых) настройках параметров и отборов СКД.

13.11.2018    19108    Unk92    18       

Автоматические и управляемые блокировки применительно к типовым конфигурациям 1С 125

Статья Программист Нет файла v8 v8::blocking 1cv8.cf Бесплатно (free) Математика и алгоритмы Практика программирования

Основные принципы работы с режимами автоматических и управляемых блокировок в 1С Предприятие 8. Теория и применение в типовых конфигурациях: БП, УТ, ЕРП

10.11.2018    20557    ids79    40       

Создание телеграм бота с гугл авторизацией, обратными вызовами и уведомлениями об обновлении через сервер-маршрутизатор 157

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) WEB

Статья детально рассказывает обо всех аспектах настройки телеграм бота, работающего через сервер-маршрутизатор посредством обратных вызовов. Приведены примеры работы отправки/исправления сообщений, отправки файлов, работы с внутренними и встроенными запросами. Создание клавиатуры. Авторизация пользователей через gmail.

07.11.2018    17070    🅵🅾️🆇    40       

Вспомогательные инструкции в коде 1С 104

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования

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

15.10.2018    20200    tormozit    100       

Произвольный код в фоновом режиме 163

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования

Задача: реализовать выполнение произвольного кода в фоновом режиме без изменения конфигурации, т.е. во внешней обработке.

03.09.2018    14385    nikita0832    41       

Основные понятия и механизмы оптимизации клиент-серверного взаимодействия в 1C 144

Статья Программист Нет файла v8 Россия Бесплатно (free) Математика и алгоритмы Практика программирования

У многих начинающих 1С программистов часто возникают вопросы про клиент-серверное взаимодействие в 1С и чтобы разобраться в непростых механизмах платформы, необходимо понять, что же такое контекст, для чего предназначены директивы компиляции, что представляют собой контекстные/внеконтекстные вызовы и как наиболее оптимально описывать прикладные задачи в модулях управляемых форм.

23.08.2018    20870    Rain88    42       

Повышаем эффективность разработки правил обмена 122

Статья Программист Нет файла v8 КД ОС Бесплатно (free) Практика программирования Перенос данных из 1C8 в 1C8

Как повысить скорость и качество разработки правил обмена? Как вести групповую разработку правил обмена? Как облегчить сопровождение правил обмена после передачи в эксплуатацию? Об этом и многом другом вы можете узнать из этой статьи.

25.06.2018    19108    olegtymko    43       

На что действительно способны HTTP-сервисы 169

Статья Программист Нет файла v8 Бесплатно (free) WEB

В статье я собираюсь не только рассказать вам про HTTP-сервисы 1С, но и показать много прикольных слайдов с картинками. Я думаю, будет весело, и вы найдете для себя что-то полезное.

14.06.2018    22303    dalgaso2010    44       

Введение в механизм представлений в ЗУП ред. 3 152

Статья Программист Нет файла v8 v8::СПР ЗУП3.x Бесплатно (free) Практика программирования

В нашей организации на первом же телефонном собеседовании на должность разработчика по ЗУП ред. 3 вас обязательно спросят о том, что такое "Представления".

04.06.2018    24083    xrrg    82       

Как сделать запрос на изменение данных 75

Статья Программист Нет файла v8 v8::Запросы 1cv8.cf Бесплатно (free) Практика программирования

В статье приведены особенности внутренней архитектуры и примеры работы с расширением языка запросов 1С.

01.06.2018    21011    m-rv    21       

Строим графы средствами 1С (без GraphViz) 42

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования

Множество статей на Инфостарте описывают, как работать с компонентой GraphViz, чтобы построить ориентированный граф. Но практически нет материалов, как работать с такими графами средствами 1С. Сегодня я расскажу, как красиво строить графы с минимальным пересечением. Нам этот метод пригодился для отрисовки алгоритмов в БИТ.Финансе, т.к. типовой механизм не устраивал. Еще это может быть полезно для визуализации различных зависимостей: расчета себестоимости, графы аффилированности компаний и т.д. Надеюсь, эта статья поможет сделать мир 1С красивее и гармоничней:) Итак, поехали...

23.05.2018    16801    slozhenikin_com    19       

Распределение расходов пропорционально продажам 9

Статья Программист Пользователь Нет файла v8 v8::ОУ УТ10 УУ Финансовый учет и бюджетирование (FRP) Учет доходов и расходов Бесплатно (free) Практика программирования

Финансовая модель. Распределение административных расходов по подразделениям пропорционально продажам за месяц. Дополнительные реквизиты против бизнес-процессов!

13.05.2018    11201    Rustig    9       

Просмотр временных таблиц запроса в отладчике без изменения кода 126

Статья Программист Нет файла v8 v8::Запросы 1cv8.cf Бесплатно (free) Практика программирования

Данный способ можно использовать для просмотра содержимого временных таблиц запросов (менеджеров временных таблиц) без внесения изменений в код.

24.04.2018    23939    avfed@rambler.ru    19       

Минимализмы 3 350

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Универсальные функции

Очередная серия "минимализмов" [http://infostart.ru/public/306536/, https://infostart.ru/public/460935/]. Также, как и в предыдущих статьях, здесь приведена подборка коротких оригинальных авторских решений некоторых задач. Ранее эти решения были разбросаны по моим комментариям к чужим публикациям.

19.02.2018    35249    ildarovich    44       

Готовим Soap для Web-сервисов. Рецепты 130

Статья Программист Нет файла v8 Россия Windows Бесплатно (free) WEB

В статье описаны различные варианты обмена данными с web-сервисами по протоколу Soap, основанные на личном опыте.

28.12.2017    28465    987ww765    27       

Этюды по программированию. Взаимодействие с Microsoft Word 108

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования

Часто приходится заниматься созданием сложных документов Word с таблицами, вложенными фрагментами, хитрым оформлением и прочими радостями жизни. Это - попытка как-то структурировать полученный опыт, чтобы не приходилось перерывать ворох старых обработок в поисках крупиц истины. Надеюсь, эта статья будет полезна и Вам.

11.12.2017    25667    milkers    23       

Метод формирования движений в типовых регистрах нетиповыми регистраторами 31

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования

Вариант решения задач с проведением по типовым регистрам нетиповыми регистраторами. Зачем - чтобы при сравнении конфигурации не обращать внимание на свойства регистров и исключить вероятность допущения горькой оплошности при обновлении информационных баз, заменив типы регистраторов основной конфигурации типами конфигурации поставщика. Для программных продуктов, имеющих в своем составе метаданных документ "Корректировка регистров"("Корректировка записей регистров").

05.12.2017    21150    itriot11    34       

1С: Конвертация данных 3. Инструкции и примеры. EnterpriseData (универсальный формат обмена) 717

Статья Программист Нет файла v8 КД Бесплатно (free) Перенос данных из 1C8 в 1C8 Практика программирования Обмен через XML

Что такое КД3? Как начать использовать? Полезные дополнения к документации. Что нужно исправить в типовых обработках и конфигурации. Как изменить правила обмена не снимая конфигурацию с поддержки. Как отлаживать правила обмена?

19.11.2017    136379    MaxS    251       

Заполнение данных по ИНН контрагента с помощью альтернативного сервиса огрн.онлайн 131

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования

Код для заполнения данных по ИНН контрагента из ЕГРЮЛ с сайта огрн.онлайн.

01.11.2017    22476    slava_1c    49       

Программные перечисления, ч.2: приемы кэширования при разработке 65

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования

Все знают, что такое кэш, и зачем он нужен. Но в 1С разработчик обычно использует кэширование только на уровне конфигурации, а в какой-нибудь обработке скорее ломает голову над запросом - как получить все данные за один заход... Хочется рассказать о том, как можно добиться хороших результатов с стратегией "разделяй и властвуй".

30.10.2017    20904    unichkin    17       

Разбираемся с настройками компоновки данных 159

Статья Программист Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования

Краткая шпаргалка по программной работе с настройками СКД

29.10.2017    23850    json    9       

Работа с Excel 287

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Загрузка и выгрузка в Excel

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

23.10.2017    24248    arakelyan    39       

Добавление команд печати в конфигурациях на БСП 2.4.3 (в частности, в самописных документах в Бухгалтерии 3.0 после релиза 3.0.52.35) 143

Статья Программист Нет файла v8 v8::БУ БП3.0 Россия Бесплатно (free) Печатные формы документов Практика программирования БСП (Библиотека стандартных подсистем)

В статье https://infostart.ru/public/237013/ пользователя nick max рассматривался список действий для подключения команд печати в Бухгалтерии 3.0, работающей на БСП 2.3.6. В новом релизе Бухгалтерии 3.0.52.35 от 15.09.2017г. стала использоваться БСП 2.4.3, из-за чего произошли изменения в процедурах общих модулей, связанных с механизмом печати, и в процедурах их вызова в формах документов и в формах списков. Рассмотрим их.

18.09.2017    46313    bugtester    43       

Отказ от работы с временными файлами при работе с двоичными данными или Потоки как простая замена ADODB.Stream и временным файлам 126

Статья Программист Нет файла v8 Россия Бесплатно (free) Практика программирования

В платформе начиная с версии 3.8.9 (как я понял по документации) появился расширенный функционал средств работы с двоичными данными. Если раньше простой и очевидный способ преобразования данных строился на использовании временных файлов, то теперь благодаря новым средствам можно уйти от их использования.

12.09.2017    18043    vardeg    31