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

Публикация № 547389 07.09.16

Разработка - Механизмы платформы 1С

.Net Core Scripting API <blockquote>

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

Это продолжение статей Кроссплатформенное использование классов .Net в 1С через Native ВК. Или замена COM на Linux
Кроссплатформенное использование классов .Net в 1С через Native ВК. Или замена COM на Linux II
Асинхронное программирование в 1С через использование классов .Net из Native ВК
1С, Linux, Excel, Word, OpenXML, ADO, Net Core

На данный момент в .Net Core 2 варианта динамической компиляции 1. Это аналог CodeDom Microsoft.CodeAnalysis.CSharp.CSharpCompilation 
2. Roslyn Scripting Api. Примеры здесь

    var compilation = Microsoft.CodeAnalysis.CSharp.CSharpCompilation.Create("a")
    .WithOptions(new Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions(Microsoft.CodeAnalysis    .OutputKind.DynamicallyLinkedLibrary))
    .AddReferences(
     Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location))
    .AddSyntaxTrees(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseText(
        @"
          using System;

          public  class C
          {
  
            public  C(){}
            public string  M()
              {
               return ""Hello Roslyn."";
             }
           }"));

      var fileName = @"d:\NetStandart\TestCoreNetApp\src\TestCoreNetApp\bin\Debug\netcoreapp1.0\a.dll";

      compilation.Emit(fileName);

      var a = System.Runtime.Loader.AssemblyLoadContext.Default.LoadFromAssemblyPath(fileName);


      Type тип = a.GetType("C");
      var obj = Activator.CreateInstance(тип);

      var res = тип.GetMethod("M").Invoke(obj, null);
      Console.WriteLine(res.ToString());


 Этот подход хорош, когда нужно обновить библиотеку. Но при этом создается DLL со всеми вытекающими.

 Второй способ мне нравится больше. Возьмем на примере получения делегата.

            string words = "надо заменить все первые буквы в словах на заглавные";
            string pattern = @"\w+";
                        
            var scr = Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default;
            var mscorlib = Assembly.Load(System.Runtime.Loader.AssemblyLoadContext.GetAssemblyName(@"c:\Users\Smirnov_SA\.nuget\packages\Microsoft.NETCore.Portable.Compatibility\1.0.1\ref\netcore50\mscorlib.dll"));
            scr =scr.WithReferences(mscorlib, typeof(MulticastDelegate).GetTypeInfo().Assembly, typeof(System.Runtime.CompilerServices.IStrongBox).GetTypeInfo().Assembly, typeof(MatchEvaluator).GetTypeInfo().Assembly, typeof(Regex).GetTypeInfo().Assembly)
            .WithImports("System", "System.Text.RegularExpressions");


            string КодДелегата = @"return (MatchEvaluator)((match) =>
            {
              string x = match.Value;
            // If the first char is lower case...
                if (char.IsLower(x[0]))
                {
                  // Capitalize it.
                    return char.ToUpper(x[0]) + x.Substring(1, x.Length - 1);
                }
                  return x;

            });";
            var result = Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.EvaluateAsync(КодДелегата, scr).Result;
                  MatchEvaluator evaluator = (MatchEvaluator)result;
            
            Console.WriteLine(Regex.Replace(words, pattern, evaluator));


 Обязательно нужно указать ссылки на:
   mscorlib.dll
   System.Private.CoreLib.ni.dll
   System.Runtime.dll 


 Для компиляции используются следующие библиотеки:
   "Microsoft.CodeAnalysis.CSharp": "2.0.0-beta3",
    "Microsoft.CodeAnalysis.CSharp.Scripting": "2.0.0-beta3",
    "Microsoft.CodeAnalysis.Scripting.Common": "2.0.0-beta3",
     Microsoft.CodeAnalysis.Scripting


   По динамической компиляции. В свое время работал с запчастями для автомобилей. А там куча поставщиков и клиентов. При этом прайсы на миллионы позиций. И каждый горазд давать данные в своем формате.  Было проще для каждого клиента создавать код,  записывать в справочник и использовать через Выполнить или Вычислить. Правда, при работе с миллионными прайсами этот подход тормозил.
 
Так или иначе приходилось писать DLL и работать через COM.

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


 Скорость компиляции достаточно высокая (кроме первого раза секунд 5).


 Перейдем к 1С. Так воторй алгоритм на 1С выглядит так

            стр  = "return (MatchEvaluator)((match) =>
            |{
            |  string x = match.Value;
            |// If the first char is lower case...
            |if (char.IsLower(x[0]))
            |{
            |// Capitalize it.
            |return char.ToUpper(x[0]) + x.Substring(1, x.Length - 1);
            |}
            |return x;
            |
            |});";
            
            текст = "надо заменить все первые буквы в словах на заглавные";
            Образец = "\w+";
            // MatchEvaluator evaluator = (MatchEvaluator)ПолучитьДелегат();
            ScriptOptions=ъТип("Microsoft.CodeAnalysis.Scripting.ScriptOptions","Microsoft.CodeAnalysis.Scripting");
            CSharpScript=ъТип("Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript","Microsoft.CodeAnalysis.CSharp.Scripting");

            scr = ъ(ScriptOptions.Default);
            mscorlibСборка = ъ(Врап.Сборка("mscorlib.dll",Истина));
            Private_CoreLibСборка=ъ(Врап.Сборка("System.Private.CoreLib.ni",Истина));
            System_RuntimeСборка=ъ(Врап.Сборка("System.Runtime",Истина));
            RegularExpressionsСборка=ъ(Врап.Сборка("System.Text.RegularExpressions",Истина));
            Regex=ъ(RegularExpressionsСборка.GetType("System.Text.RegularExpressions.Regex"));
            scr =ъ(scr.WithReferences(mscorlibСборка.ПолучитьСсылку(), Private_CoreLibСборка.ПолучитьСсылку(), System_RuntimeСборка.ПолучитьСсылку(), RegularExpressionsСборка.ПолучитьСсылку()));
            
            scr =ъ(scr.WithImports("System", "System.Text.RegularExpressions"));

            evaluator = ъ(ъ(CSharpScript.EvaluateAsync(стр, scr.ПолучитьСсылку())).Result);
            Сообщить(Regex.Replace(текст, Образец, evaluator.ПолучитьСсылку()));


В общем, ничего особенного. Получили сборки, дали ссылки на них, скомпилировали, вызвали.

Перейдем к более сложным примерам. Так, в предыдущей статье я показывал примеры использования DocumentFormat.OpenXml на примере чтения Excel и Word.

Там была проблема в скорости из-за приведения строки к объекту через функцию, и сама скорость вызова из 1С в 5 раз медленнее её родного кода.

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

Создадим класс и скопируем его в макет. Суть класса - прочитать данные ячеек и сгруппировать их по номеру строки

public class ДанныеЯчейки
    {

        public string ИмяЯчейки;
        public string ИмяКолонки;
        public int НомСтроки;
        public string ЗначениеЯчейки;

    }
    public class ExcelReader
    {
        static Regex ШаблонКолонки = new Regex("[A-Za-z]+");
        OpenXmlElementList ОбщиеСтроки;

        void ЗаписатьДанныеАдреса(string адрес, ДанныеЯчейки данныеЯчейки)
        {

            данныеЯчейки.ИмяЯчейки = адрес;
            var match = ШаблонКолонки.Match(адрес);
            var ИмяКолонки = match.Value;
            var НомерСтроки = int.Parse(адрес.Substring(ИмяКолонки.Length));
            данныеЯчейки.ИмяКолонки = ИмяКолонки;
            данныеЯчейки.НомСтроки = НомерСтроки;

        }
        void ДобавитьДанныеОбЯчейке(List<ДанныеЯчейки> ДанныеЭселя, Cell cell)
        {
            var адрес = cell.CellReference.InnerText;
            var text = cell.CellValue?.Text;
            var DataType = cell.DataType;
            string res = text;
            if (DataType != null && DataType == CellValues.SharedString)
            {
                int ssid = int.Parse(text);
                res = ОбщиеСтроки[ssid].InnerText;
            }

            if (res == null) return;

            var result = new ДанныеЯчейки();
            ЗаписатьДанныеАдреса(адрес, result);
            result.ЗначениеЯчейки = res;

            ДанныеЭселя.Add(result);
        }
        public List<ДанныеЯчейки> ReadExcel(string fileName)
        {
            List<ДанныеЯчейки> ДанныеЭселя = new List<ДанныеЯчейки>();
            using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (SpreadsheetDocument doc = SpreadsheetDocument.Open(fs, false))
                {
                    var workbookPart = doc.WorkbookPart;

                    // Строки хранятся отдельно
                    // В ячейках хранится индекс
                    var pt = workbookPart.GetPartsOfType<SharedStringTablePart>();
                    var sstpart = pt.First();
                    var sst = sstpart.SharedStringTable;
                    ОбщиеСтроки = sst.ChildElements;

                    var workbook = workbookPart.Workbook;

                    // Получим список страниц
                    var sheet = workbook.Descendants<Sheet>().First();

                    var worksheetPart = (DocumentFormat.OpenXml.Packaging.WorksheetPart)workbookPart.GetPartById(sheet.Id);

                    var worksheet = worksheetPart.Worksheet;

                    var cells = worksheet.Descendants<Cell>();


                    // One way: go through each cell in the sheet
                    foreach (Cell cell in cells)
                    {
                        ДобавитьДанныеОбЯчейке(ДанныеЭселя, cell);
                    }
                }
            }

            return ДанныеЭселя;
        }

        static string НайтиИмяПоследнейКолонки(List<ДанныеЯчейки> Тз)
        {
            var рез = "";
            var ДлинаРез = 0;
            foreach (var стрТз in Тз)
            {
                var Стр = стрТз.ИмяКолонки;
                var СтрДл = Стр.Length;

                if (СтрДл > ДлинаРез)
                {
                    ДлинаРез = СтрДл;
                    рез = Стр;
                }
                else if (СтрДл == ДлинаРез && string.Compare(Стр, рез, true) > 0)
                    рез = Стр;

            }
            return рез;
        }

        public static object ПолучитьДанныеЭкселя(string fileName)
        {

            var res = new ExcelReader();
            var Данные = res.ReadExcel(fileName);
            var данныеЭкселя = Данные.GroupBy(ё => ё.НомСтроки).Select(ъ => new { НомСтроки = ъ.Key, Ячейки = ъ.ToArray() }).OrderBy(ь => ь.НомСтроки);
            var ИмяПоследнейКолонки = НайтиИмяПоследнейКолонки(Данные);
            return new { ДанныеЁкселя = данныеЭкселя.ToList(), ИмяПоследнейКолонки = ИмяПоследнейКолонки };

        }

     }

             return new Func<string, object>(ExcelReader.ПолучитьДанныеЭкселя);

 

Мы описали класс чтения и возвращаем ссылку на делегат, принимающий путь к файлу и возвращающий анонимный класс. Все равно в 1С мы будем работать с ним через рефлексию. Обратите внимание, что здесь описаны 2 класса.

Теперь вызовем этот код из 1С.

 

        ScriptOptions=ъТип("Microsoft.CodeAnalysis.Scripting.ScriptOptions","Microsoft.CodeAnalysis.Scripting");
	CSharpScript=ъТип("Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript","Microsoft.CodeAnalysis.CSharp.Scripting");
	
	scr = ъ(ScriptOptions.Default);
	mscorlibСборка = ъ(Врап.Сборка("mscorlib.dll",Истина));
	Private_CoreLibСборка=ъ(Врап.Сборка("System.Private.CoreLib.ni",Истина));
	System_RuntimeСборка=ъ(Врап.Сборка("System.Runtime",Истина));
	RegularExpressionsСборка=ъ(Врап.Сборка("System.Text.RegularExpressions",Истина));
	OpenXmlСбока=ъ(Врап.Сборка("DocumentFormat.OpenXml.dll"));
	LinqСбока=ъ(Врап.Сборка("System.Linq", истина));
	FileSystemСбока=ъ(Врап.Сборка("System.IO.FileSystem", истина));
	
	Regex=ъ(RegularExpressionsСборка.GetType("System.Text.RegularExpressions.Regex"));
	scr =ъ(scr.WithReferences(mscorlibСборка.ПолучитьСсылку(), Private_CoreLibСборка.ПолучитьСсылку(), System_RuntimeСборка.ПолучитьСсылку(), RegularExpressionsСборка.ПолучитьСсылку(),OpenXmlСбока.ПолучитьСсылку(),LinqСбока.ПолучитьСсылку(),FileSystemСбока.ПолучитьСсылку()));
	scr =ъ(scr.WithImports("System", "System.Collections.Generic", "System.Linq", "System.IO", "DocumentFormat.OpenXml", "DocumentFormat.OpenXml.Packaging", "DocumentFormat.OpenXml.Spreadsheet", "System.Text.RegularExpressions"));
	
	Текст=ПолучитьМакет("ТекстКлассаЧтенияЕксель").ПолучитьТекст();
	
	Делегат = ъ(ъ(CSharpScript.EvaluateAsync(Текст, scr.ПолучитьСсылку())).Result);
	Данные= ъ(Делегат.DynamicInvoke(ИмяФайла));
	
	Сообщить(Данные.ИмяПоследнейКолонки);
	
	рез=новый ТаблицаЗначений;
	ПоследняяКолонка=Данные.ИмяПоследнейКолонки;
	СоздатьКолонки(рез.Колонки,ПоследняяКолонка);
	Колонки=рез.Колонки;
	
	Тз=ъ(Данные.ДанныеЁкселя);
	Тз=ъ(Врап.ПолучитьЭнумератор(Тз.ПолучитьСсылку()));
	
	сч=1;
	// Получили сгруппированные данные по строкам
	Пока Тз.MoveNext() Цикл
		стрТз= ъ(Тз.Current);
		
		НомСтроки=стрТз.НомСтроки;
		Пока сч<НомСтроки Цикл
			сч=сч+1;
			рез.Добавить();
		КонецЦикла;
		сч=сч+1;
		стр=рез.Добавить();
		
                // получим ячейки по строке
		ТзГр=ъ(стрТз.Ячейки);
		ТзГр=ъ(Врап.ПолучитьЭнумератор(ТзГр.ПолучитьСсылку()));
		
		Пока ТзГр.MoveNext() Цикл
			стрТзГр= ъ(ТзГр.Current);
			ИмяКолонки=стрТзГр.ИмяКолонки;
			ЗначениеЯчейки=стрТзГр.ЗначениеЯчейки;
			// Можно конечно получить индекс зная смещение символа 64 относительно 1 и 26 разрядную систему
			// но найдем колонку по имени и её индекс
			Колонка=Колонки.Найти(ИмяКолонки);
			стр.Установить(Колонки.Индекс(Колонка),ЗначениеЯчейки); 
		КонецЦикла;	
	КонецЦикла;

Теперь скорость обработки Экселя значительно увеличилась, а затраты на компиляцию соизмеримы с затратами на чтения файлов.

Посмотрим процесс чтения Word. Не мудрствуя лукаво, я взял готовый класс здесь. Тем более там все на английском.

 

// Исходники можно скачать здесь
    //https://code.msdn.microsoft.com/office/CSOpenXmlGetPlainText-554918c3/sourcecode?fileId=71592&pathId=851860130
    public class GetWordPlainText : IDisposable
    {
        // Specify whether the instance is disposed. 
        private bool disposed = false;

        // The word package 
        private WordprocessingDocument package = null;

        /// <summary> 
        ///  Get the file name 
        /// </summary> 
        private string FileName = string.Empty;

        /// <summary> 
        ///  Initialize the WordPlainTextManager instance 
        /// </summary> 
        /// <param name="filepath"></param> 
        public GetWordPlainText(string filepath)
        {
            this.FileName = filepath;
            if (string.IsNullOrEmpty(filepath) || !File.Exists(filepath))
            {
                throw new Exception("The file is invalid. Please select an existing file again");
            }

            this.package = WordprocessingDocument.Open(filepath, true);
        }

        /// <summary> 
        ///  Read Word Document 
        /// </summary> 
        /// <returns>Plain Text in document </returns> 
        public string ReadWordDocument()
        {
            StringBuilder sb = new StringBuilder();
            OpenXmlElement element = package.MainDocumentPart.Document.Body;
            if (element == null)
            {
                return string.Empty;
            }

            sb.Append(GetPlainText(element));
            return sb.ToString();
        }

        /// <summary> 
        ///  Read Plain Text in all XmlElements of word document 
        /// </summary> 
        /// <param name="element">XmlElement in document</param> 
        /// <returns>Plain Text in XmlElement</returns> 
        public string GetPlainText(OpenXmlElement element)
        {
            StringBuilder PlainTextInWord = new StringBuilder();
            foreach (OpenXmlElement section in element.Elements())
            {
                switch (section.LocalName)
                {
                    // Text 
                    case "t":
                        PlainTextInWord.Append(section.InnerText);
                        break;

                    case "cr":                          // Carriage return 
                    case "br":                          // Page break 
                        PlainTextInWord.Append(Environment.NewLine);
                        break;

                    // Tab 
                    case "tab":
                        PlainTextInWord.Append("\t");
                        break;

                    // Paragraph 
                    case "p":
                        PlainTextInWord.Append(GetPlainText(section));
                        PlainTextInWord.AppendLine(Environment.NewLine);
                        break;

                    default:
                        PlainTextInWord.Append(GetPlainText(section));
                        break;
                }
            }

            return PlainTextInWord.ToString();
        }

        #region IDisposable interface 

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            // Protect from being called multiple times. 
            if (disposed)
            {
                return;
            }

            if (disposing)
            {
                // Clean up all managed resources. 
                if (this.package != null)
                {
                    this.package.Dispose();
                }
            }

            disposed = true;
        }
        #endregion

        public static string GetText(string FileName)
        {

            using (var pt = new GetWordPlainText(FileName))
            {

                return pt.ReadWordDocument();
            }
        }
    }
    
    return new Func<string,string>(GetWordPlainText.GetText);

 

Но вернемся к Руслишу:

        ScriptOptions=ъТип("Microsoft.CodeAnalysis.Scripting.ScriptOptions","Microsoft.CodeAnalysis.Scripting");
	CSharpScript=ъТип("Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript","Microsoft.CodeAnalysis.CSharp.Scripting");
	
	scr = ъ(ScriptOptions.Default);
	mscorlibСборка = ъ(Врап.Сборка("mscorlib.dll",Истина));
	Private_CoreLibСборка=ъ(Врап.Сборка("System.Private.CoreLib.ni",Истина));
	System_RuntimeСборка=ъ(Врап.Сборка("System.Runtime",Истина));
	RegularExpressionsСборка=ъ(Врап.Сборка("System.Text.RegularExpressions",Истина));
	OpenXmlСбока=ъ(Врап.Сборка("DocumentFormat.OpenXml.dll"));
	LinqСбока=ъ(Врап.Сборка("System.Linq", истина));
	FileSystemСбока=ъ(Врап.Сборка("System.IO.FileSystem", истина));
	
	Regex=ъ(RegularExpressionsСборка.GetType("System.Text.RegularExpressions.Regex"));
	scr =ъ(scr.WithReferences(mscorlibСборка.ПолучитьСсылку(), Private_CoreLibСборка.ПолучитьСсылку(), System_RuntimeСборка.ПолучитьСсылку(),OpenXmlСбока.ПолучитьСсылку(),FileSystemСбока.ПолучитьСсылку()));
	scr =ъ(scr.WithImports("System", "System.Text",  "System.IO", "DocumentFormat.OpenXml", "DocumentFormat.OpenXml.Packaging"));
	
	Текст=ПолучитьМакет("ТекстЧтенияВорд").ПолучитьТекст();
	
	Делегат = ъ(ъ(CSharpScript.EvaluateAsync(Текст, scr.ПолучитьСсылку())).Result);
	стр = Делегат.DynamicInvoke(ИмяФайла);
	
	Текст=Новый ТекстовыйДокумент;
	Текст.ДобавитьСтроку(стр);
	Текст.Показать();

 

Основная задача указать ссылки на используемые сборки и пространство имен.

В следующей статье я сделаю динамическое создание обертки над объектами, использующими события, по аналогии с
.NET(C#) для 1С. Динамическая компиляция класса обертки для использования .Net событий в 1С через ДобавитьОбработчик или ОбработкаВнешнегоСобытия

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

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. cool.vlad4 2 07.09.16 15:52 Сейчас в теме
+1. все это прикольно. но ума не приложу, как в реале писать в итоге код таким образом . выходной код , напоминает код с которым я как-то сталкивался , - powershell , который динамически компилит огромную простыню C# кода , аналогично, производит всякие действия, и в итоге получается результат. попытки что-либо изменить , приводили к ошибкам. оттестировать, тоже было непонятно как. в итоге , я переписал все на C# . но вот в случае с 1С, как быть . на самом деле использовать dotnet , идея заманчивая , появляется в среде 1С периодически на протяжении долгого периода времени. но вот как сделать хорошую интеграцию на уровне кода, пока непонятно. я к примеру, недавно написал COM компоненту, на C# , которая по заданному шаблону docx , формирует документ. мне это проще. нежели писать такой код:

scr = ъ(ScriptOptions.Default);
mscorlibСборка = ъ(Врап.Сборка("mscorlib.dll",Истина));
Private_CoreLibСборка=ъ(Врап.Сборка("System.Private.CoreLib.ni",Истина));
System_RuntimeСборка=ъ(Врап.Сборка("System.Runtime",Истина));
RegularExpressionsСборка=ъ(Врап.Сборка("System.Text.RegularExpressions",Истина));
OpenXmlСбока=ъ(Врап.Сборка("DocumentFormat.OpenXml.dll"));
LinqСбока=ъ(Врап.Сборка("System.Linq", истина));
FileSystemСбока=ъ(Врап.Сборка("System.IO.FileSystem", истина));
и т.д.

есть мысли как бороться со сложностью читаемости и сопровождения результируещего кода?
утюгчеловек; +1 Ответить
2. Serginio 918 07.09.16 16:01 Сейчас в теме
Ну проблема для начало в том, что в Native API нельзя возвращать объекты. Поэтому приходится возвращать строку и из неё создавать ВК.

//1С при передаче по ссылке свойства ВК Список.Current
// при выходе из метода присваивает  Список.Current значение переданное изначально
// Поэтому помечаем входной параметр как Знач
//Или же делать так, если методы изменить нельзя 
// То нужно присвоить значение переменной и вызвать метод передав в параметрах эту переменную
//Стр=Список.Current; 
//Зазача=ъ(Стр);
Функция Ъ(знач Ссылка)
	
	// Создаем объект по ссылке полученной из методов .Net классов
	//Физически это строка ёЁ<Ьъ>№_%)Э?&2 содержащее 12 символов для отделения их от других строк
	//и индекс в спике исполуемых объектов на стороне .Net
	
	рез = Новый("AddIn.NetObjectToNative.NetObjectToNative");
	// И установим ссылку
	рез.УстановитьСсылку(Ссылка);    
	возврат  рез
КонецФункции // СоздатьОбъектПоСсылке()
Показать


Кстати на данные момент я не могу написать DLL для Core .Net для использования OpenXML. Нужно, что бы компонент был в NuGet.
Кроме того я предполагаю использовать динамическую компиляцию для обертки событий.
3. cool.vlad4 2 07.09.16 16:08 Сейчас в теме
(2) это да. вот и получается , что придется либо переизобретать тот же COM, либо делать подобные workaround. но просто выходной код получается, уж очень непростым для сопровождения. примеры-то простые. в более сложных случаях будет еще более увесистый код.
4. Serginio 918 07.09.16 16:14 Сейчас в теме
(3) Я это прекрасно понимаю. Вообще эти разработки для того, что бы подвинуть 1С к изменению своей политики. На самом деле нет особых причин не использовать объекты в параметрах или при возврате объекта из метода.

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

1. Абсолютно не нужны методы FindMethod, FindProp, IsPropReadable, IsPropWritable, GetNParams, HasRetVal, GetParamDefValue

Так как у методов

bool CallAsProc

bool CallAsFunc

bool SetPropVal и bool GetPropVal есть возвращаемое значение об успешном выполнении

Информация об ошибке возвращается через AddError.

Да и вызов по индексу это анахронизм от IDiapatch, где было описание диспинтерфейсов для увеличения скорости вызова.

2. При возвращении методами SetPropVal и GetPropVal исключение не вызывается

3. Зачем-то происходит установка свойств там, где в коде этого не требуется.

4. Вызывается метод как функция там, где метод вызывается как процедура.

5. Один из основных - это нельзя вернуть и передать экземпляр ВК из методов ВК.

Я лично не вижу никаких проблем. Определить значение для такого типа
Показать
duhin; cool.vlad4; +2 Ответить
6. Serginio 918 07.09.16 16:57 Сейчас в теме
(3) Код то будет аналогичным. Нужно просто добавить ссылки на используемые DLL и пространства имен.
ссылки на DLL можно передавать в виде путей
5. Serginio 918 07.09.16 16:15 Сейчас в теме
Кроме того

Например практически все программисты 1С используют ComОбъект.

По моей методе можно использовать
NetОбъект,NetТип
JavaОбъект,JavaТип

И эти объявления будут реально кроссплатформенны.
При это различия с ComОбъект минимальны. Имя класса равноценно комовскому ProgID. При этом нет ограничений на используемые типы.
Ты можешь написать свою библиотеку поместить в определенное место и использовать её вместо COM. Без регистрации итд. Расширять возможности 1С станет легче.

Например сейчас в конфигураторе куча функций, которые есть в стандартных библиотеках. При этом функционал 1С функций сильно недотягивает до стандартных библиотек.
Учитывая кроссплатформенность можно использовать нетовские или явовские библиотеки везде где можно. Упрощая программирование.
А что касается работы с HTTP,SMPT, JSON то эти библиотеки были задолго до того как 1С их реализовывала, при этом с ошибками и функционалом сильно недотягивающих до .Net или Java.
Стоит ли тратить время на то, что можно взять из стандартных библиотек. А ведь можно легко расширить за счет своих сборок.

При этом например нетовская библиотека весит всего 65 мегабайт, которую можно включить в дистрибутив и главное это кроссплатформенное решение. Причем нет ничего сложного передавать в параметрах и объекты 1С которые поддерживают аналогичный интерфейс. Можно пойти по пути подсчета ссылок в 1С, а доступ к объектам 1С только на время вызова метода ВК.

Например Использование сборок .NET в 1С 7.x b 8.x. Создание внешних Компонент многие бы использовали на равне с ComОбъект, но главная причина её неприменения в том, что она неинтегрирована в 1С.

Даже если 1С не хочет интегрировать .Net в 1С, то можно сделать вариант ВК под .Net и Java . Прежде всего для получения объектов ВК и передачи их в параметрах. Кроме того можно добавить доступ по индексу [], получения итератора.
Оставьте свое сообщение

См. также

Методы работы с универсальным отчетом в подсистеме "Варианты отчетов" на БСП

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данной статье рассмотрим типовую подсистему "Варианты отчетов" БСП на примере применения в универсальном отчете любой современной конфигурации.

вчера в 13:00    1199    quazare    2    

49

Снова об использовании ТекущаяДата() на клиенте и на сервере и о работе в разных часовых поясах

БСП (Библиотека стандартных подсистем) Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Можно ли применять ТекущаяДата() вопреки требованиям стандартов 1С? Безопасно ли использование функции ОбщегоНазначенияКлиент.ДатаСеанса() из БСП? Как правильно поступать при работе пользователей в разных часовых поясах?

24.04.2023    4048    Alxby    26    

40

Самодельный обработчик ПослеЗаписи объекта

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Иногда при записи объекта хочется обработчик ПослеЗаписи, который бы выполнялся всегда после успешного завершения транзакции записи объекта. Статья описывает способ реализации такого обработчика.

03.04.2023    2826    tormozit    63    

39

Расширение глобального поиска 1С, или Глобальный поиск "на максималках"

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Мало кто знает, что поле "Глобального поиска" в 1С можно доработать. Добавить свои варианты поиска, кнопочки в результатах и даже целые пользовательские меню.

27.03.2023    4197    SeiOkami    9    

121

Postgres как предчувствие. Вычисляем процент импортозамещения в режиме Highload от 1С

HighLoad оптимизация Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

1С работает с СУБД Postgres более 10 лет, а сейчас это единственный легальный вариант для инсталляций в России. Много ли мы потеряем в производительности по сравнению с MS SQL? Выдержит ли Postgres 15.2 жесткий Highload со стороны 1С? Цель этой статьи - ответить на данные вопросы, с цифрами, которые можно использовать при расчете архитектуры.

23.03.2023    1647    1CUnlimited    9    

28

Версионирование объектов VS История данных

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Давайте разберемся в механизме «История данных» и поэкспериментируем для наглядности. Сравним «Версионирование объектов» и «Историю данных».

06.03.2023    5868    dsdred    37    

126

Оператор GOTO в 1С - табу или волшебная палочка?

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

В ежедневной практике программирования на платформе 1С оператор Goto (Перейти) практически не встречается. Не удивительно, что половина специалистов даже не подозревает о существовании данного оператора. Ну, а знающим он внушает ужас, и его стараются избегать. Так что же это за редкий оператор, и для чего он нужен?

19.02.2023    5702    Dementor    72    

43

Идентификатор объекта в запросе. Вы этого хотели?

Запросы Механизмы платформы 1С Платформа 1С v8.3 Запросы Бесплатно (free)

В платформе 8.3.22 появилась возможность получать идентификатор в запросе. Лично я ждал этого давно, но по итогу ждал большего. Что не так?

12.01.2023    12986    dsdred    15    

68

Маленькие хитрости большой платформы (часть 1)

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Ничего сверхсекретного, просто несколько полезных приёмов, как упростить себе жизнь и ускорить разработку: от банальных советов до неочевидных, на первый взгляд, приёмов.

29.12.2022    4228    zeltyr    25    

41

Практическая шпаргалка по новым возможностям языка запросов 1С

Механизмы платформы 1С Запросы Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

В предлагаемой статье решил привести примеры применения новых возможностей языка запросов 1С, начиная с версии платформы 8.3.20.

21.11.2022    16347    quazare    34    

113

Создаем периодические реквизиты или привет из 1С 7.7

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Конечно же, платформа 1С:Предприятие 8 не поддерживает периодические реквизиты, в статье описано использование типовой методики периодических сведений в коробочных решениях от 1С.

26.10.2022    1309    morin    4    

26

Асинхронное нечто, или так, как раньше!

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Все же знают, что раньше было лучше! Возврат к истокам и погружение в детали...

23.10.2022    4779    starik-2005    38    

40

О цикле обратном замолвите слово...

Механизмы платформы 1С Языки и среды Платформа 1С v8.3 Платформа 1C v8.2 Бесплатно (free)

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

08.09.2022    6483    DrAku1a    71    

31

1С и Unicode

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Разбираемся, как 1С работает с текстом и отдельными символами в контексте Unicode.

05.09.2022    4742    Irwin    30    

80

Шпаргалка по функциям АСИНХ

Механизмы платформы 1С Платформа 1С v8.3 Россия Бесплатно (free)

При знакомстве с новой механикой работы с асинхронностью (обещание, ждать и асинх) делал пометки, которыми и хочу поделиться. Ничего сверхъестественного в них нет, просто небольшие примеры и некоторые всплывшие нюансы использования.

29.07.2022    17168    zeltyr    17    

146

Экспертный кейс. История расследования одного небыстрого закрытия месяца в 1C:ERP. Пример неочевидных путей расследования в виде детективной истории

HighLoad оптимизация Механизмы платформы 1С Запросы Платформа 1С v8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

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

11.07.2022    5757    it-expertise    27    

57

Состав индексов с дополнительным упорядочиванием на уровне СУБД (MS SQL) при индексации реквизитов

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

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

15.06.2022    3075    sinichenko_alex    9    

34

Динамическое обновление - это зло?

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Копнем глубже в тему "Что же такое динамическое обновление" и почему оно может привести к проблемам. И может ли?

09.05.2022    18272    Infostart    80    

229

Об одной неочевидной проблеме перехода на версию платформы 8.3.20

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

При переходе на платформу 8.3.20 мы столкнулись с ошибкой "Повторяющийся псевдоним "Ссылка" Ссылка AS Ссылка,Presentation AS Presentation,Ссылка AS Ссылка" в ряде типовых конфигураций. Причём, эта проблема оказались неизвестна ни Яндексу, ни Гуглу. Путём мучительных экспериментов нам удалось найти решение. Пока я ещё не уверен, действительно это решение или обходной костыль, а настоящая проблема -- в чём-то другом, но это решение работает в ситуации, когда всё сломалось, а проблему надо решать срочно. Предположительная причина: платформа 8.3.20 более строго относится к типизации данных в запросах, чем предыдущие версии, вываливая в случае несоблюдения новшеств малопонятные ошибки.

08.04.2022    6881    Kernelbug    26    

34

Отборы динамического списка

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Динамический список предоставляет несколько объектов "Отбор". В статье разбирается, какой для чего нужен и как их использовать на форме. Рассматриваются только возможности платформы (без БСП).

28.03.2022    28995    Gladkov_Anton    7    

72

Фишки платформы 1С 8.3 для начинающего разработчика

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Россия Бесплатно (free)

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

11.03.2022    11192    Dimbayyyy    98    

61

Экспертный кейс. Расследование деградации производительности системы. Проведение документа “Поступление товаров и услуг” (1С:ERP 2)

Механизмы платформы 1С Запросы HighLoad оптимизация Платформа 1С v8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

В ходе проведения нагрузочного тестирования одним из наших клиентов была выявлена сильная деградация производительности системы в целом и, в частности, выполнения ключевой операции “Проведение документа поступление товаров и услуг” в течение выполнения теста. Согласно данным подсистемы БСП “Оценка производительности”, время выполнения ключевой операции “Проведение документа поступление товаров и услуг” возрастало в процессе тестирования с 15-20 секунд в начале тестирования до 150-200 секунд в его финале.

02.03.2022    4294    it-expertise    50    

31

Модульная архитектура или пара слов о расширениях. Часть I (мысли, рассуждения)

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Статья-размышление о том, какое может быть применение технологии расширений 1С и зачем нам, разработчикам/программистам на 1С, знать общепринятые паттерны проектирования приложений. Итак, а что если я вам скажу, что технология расширений 1С - это одно из прекрасных новшеств компании 1С? Пусть эта статья будет хвалебной одой расширениям 1С.

14.02.2022    6860    amon_ra    67    

25

Синхронный и асинхронный вызов в новых версиях платформы

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Начиная с платформы 8.3.18.1128 переработана технология работы с асинхронными вызовами. В данной статье хочу описать новые асинхронные вызовы и сравнить их с предыдущими на примере функции - Вопрос на клиенте.

31.01.2022    7088    Shining_ninja    17    

37

Несколько простых приемов для удобной работы в конфигураторе

Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Простая и удобная среда разработки 1С:Предприятия позволяет практически любому человеку начать работать под капотом 1С - в конфигураторе. Время идет, новички становятся программистами, специалистами, а об удобных приемах работы узнают годами, по ходу своего карьерного пути. А здорово было бы, если бы все знали удобные приемы в начале своего пути? Эти несколько приемов будут полезны новичкам, так как они затрагивают ту область работы, с которой приходится сталкиваться в начале карьеры.

12.11.2021    13545    acces969    95    

142

Как спроектировать структуру регистра сведений

Механизмы платформы 1С Платформа 1С v8.3 Запросы Бесплатно (free)

«Что может быть проще?» — это первое, что приходит в голову. Но что, если это не так? В этой статье мы попробуем затронуть некоторые вопросы, которые могут возникнуть при проектировании больших регистров.

08.11.2021    9185    Neti    60    

108

О вложенных попытках, исключениях и о представлении ошибок

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данной статье, на небольшом примере, мне бы хотелось показать, как себя ведут вложенные "Попытка-Исключение". А также о том, чем отличаются методы ОписаниеОшибки() и ИнформацияОбОшибке().

07.11.2021    14152    Nicholas    22    

47

Обработчик ожидания. Нюансы

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

ПодключитьОбработчикОжидания: некоторые подробности и особенности работы

24.08.2021    27170    Yashazz    26    

65

Прогресс-бар в поле динамического списка

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Изображаем прогресс-бары в колонке динамического списка

23.08.2021    4702    Yashazz    13    

39

ПриПолученииДанныхНаСервере + Контекст формы. Лайфхак

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Передать свои произвольные данные в событие, которое "без контекста"? Легко!

13.08.2021    7687    Yashazz    16    

44

Новичок новичку: как добавить программно кнопку на форму путем расширения

Механизмы платформы 1С Платформа 1С v8.3 Россия Бесплатно (free)

Рассказываю очень простым языком, как добавить программно кнопку в типовую конфигурацию. Сам новичок в этом деле и рассказываю на "новичковом" языке.

13.05.2021    44818    user1312100    29    

73

Программное создание расширения

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Создание нового расширения "на лету", только штатными средствами 1С.

06.04.2021    7394    Yashazz    16    

77

Советы из Желтой тетради 📒 #1

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

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

15.03.2021    6601    builin    122    

53

Расширенный автоподбор при вводе по строке в поле ввода в управляемых формах

Механизмы платформы 1С Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Бесплатно (free)

Началось все с того, что штатный автоподбор при вводе по строке в поле ввода для некоторых больших справочников устраивать перестал. Вообще, для способа поиска строки "Любая часть" он работает на первый взгляд очень хорошо: работает как полнотекстовый (т.е. по нескольким словам) даже без активации полнотекстового поиска, красиво подсвечивает слова поиска в результатах. Казалось бы, все отлично. Но есть неприятное ограничение - всего лишь 10 значений в результирующем списке (у вас может быть несколько больше, так как платформа неявно добавляет результаты поиска по истории ввода). Для небольших справочников или справочников с разнородным ассортиментом все хорошо. Но не в моей ситуации. А простых путей увеличить количество выдаваемых строк на момент написания статьи мне обнаружить не удалось. Пришлось полностью переопределять автоподбор. Ниже речь пойдет именно об этом. И, к слову, в типовых конфигурациях для некоторых справочников используются похожие приемы для увеличения количества строк результата автоподбора.

21.01.2021    11342    herfis    9    

53

О формах 1С замолвите слово... Необычное использование знакомого всем объекта

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Неочевидно, но форму 1С можно использовать как универсальный объект, который доступен на клиенте и имеет уникальный набор свойств, методов, событий и конструктор, принимающий параметры. При этом у формы может не быть интерфейса, и ее можно даже не открывать. О реальных примерах применения такого подхода пойдет рассказ.

13.01.2021    10854    CyberCerber    46    

101

Наследование свойств элементов, или Как пользователь может сломать вашу форму

Механизмы платформы 1С Платформа 1С v8.3 Платформа 1C v8.2 Конфигурации 1cv8 Бесплатно (free)

В 1С можно установить свойства ТолькоПросмотр, Доступность и Видимость не только на элементы формы, но и на группы элементов. Но стоит ли так делать? Оказывается, пользователь может обойти запреты, которые установлены на папку. Об этом подробнее в видео.

12.01.2021    6814    SeiOkami    27    

112

Ускоряем медленный/долгий и тормозной стандартный поиск по динамическому списку, настраиваем его под себя

Механизмы платформы 1С Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Бесплатно (free)

Пользователи привыкли искать на форме списка, но, вбивая в поиск некорректные данные, могут завесить всю систему, а если еще искать нужно по НЕ полям списка, то решение только в своём поиске - все это решим в публикации с открытым кодом.

14.12.2020    41403    SizovE    2    

40