Пишем консольные exe-приложения на языке 1С

Нужен скрипт автоматизации рутинных операций? Нет времени учить JScript или VBScript? Теперь можно писать скрипты автоматизации прямо на языке 1С. Проект 1Script представляет собой альтернативную исполняющую среду этого языка.
В данной статье рассматриваются основные возможности 1Script и варианты его практического применения.

Сообщение от автора от 06.07.15

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

Все что написано ниже не удалено с инфостарта, поскольку является, как-никак, частью истории проекта.

 

Введение

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

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

Назначение и состав

Основным назначением 1Script является использование его, как самостоятельного программного продукта, предназначенного для выполнения скриптов на языке 1С в целях автоматизации администрирования. Ближайшим аналогом является инфраструктура WSH.

1Script может использовать COM-объекты WSH для взаимодействия с операционной системой, тем самым получая весьма широкие возможности.

Разумеется, область применения этим не ограничивается и именно об областях применения пойдет речь ниже.

В состав программы входят 2 основных компонента:

  1. GUI-приложение TestApp, которое позволяет экспериментировать с движком, запускать скрипты и смотреть на результат.
  2. Консольное приложение oscript, которое является «боевым» модулем, выполняющим основное назначение программы – исполнение скриптов в консоли

После установки оба этих компонента можно запускать независимо друг от друга.

Краткое описание возможностей

Основное назначение программы – возможность исполнения кода на языке 1С, но без самой 1С. Наиболее вероятное применение, как уже упоминалось – это скрипты автоматизации, аналогичные тем, что пишутся на JScript и VBScript с применением инфраструктуры WSH.

1Script позволяет использовать родные для windows COM-объекты, которые применяются в WSH. Например, если нам нужно архивировать все базы из списка баз 1С, то мы можем написать следующий скрипт:

Shell = Новый COMОбъект(«WScript.Shell»);
ПапкаПараметров = Shell.ExpandEnvironmentStrings( «%APPDATA%» );
ФайлСпискаБаз = ПапкаПараметров + «1C1CEStartibases.v8i»;

МассивСтрокСоединения = Новый Массив;
ЧтениеФайла = Новый ЧтениеТекста(ФайлСпискаБаз);

СтрокаФайла = ЧтениеФайла.ПрочитатьСтроку();
Пока
СтрокаФайла <> Неопределено Цикл

    Если Лев(СтрокаФайла, 8) = «Connect=» Тогда
       
МассивСтрокСоединения.Добавить(Сред(СтрокаФайла,9));
    КонецЕсли;

    СтрокаФайла = ЧтениеФайла.ПрочитатьСтроку();

КонецЦикла;

ЧтениеФайла.Закрыть();

КоманднаяСтрокаАрхивации = «1Cv8.exe DESIGNER %1 /DumpIB»;
Для Каждого
СтрокаСоединения Из МассивСтрокСоединения Цикл
   
РабочаяСтрокаЗапуска = СтрЗаменить(КоманднаяСтрокаАрхивации, «%1», СтрокаСоединения);
   
Shell.Run(РабочаяСтрокаЗапуска);
КонецЦикла;

В приведенном примере проверка ошибок и выбор места, в которое надо поместить архив, опущены для краткости.

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

oscript.exe [файл скрипта]

Будет прочитан список баз, из него получены строки соединения с базами и для каждой из баз выполнена процедура архивации. Обратите внимание, код на языке 1С исполняется 1Script без участия самой платформы 1С.

Возможности языка

Доступны все возможности встроенного языка, перечисленные в ветке «Описание встроенного языка» стандартного синтакс-помощника.

Исключения из этого правила перечислены в разделе «Отличия от стандартной библиотеки».

Возможно создание и использование следующих универсальных коллекций:

  • Массив
  • Структура
  • Соответствие

Доступны вспомогательные классы:

  • Консоль
  • ЧтениеТекста

Доступны глобальные методы и свойства:

  • метод Сообщить(сообщение)
  • метод ВвестиСтроку(результат, макс_длина = 0)
  • метод ЗавершитьРаботу(код_возврата)
  • метод Приостановить(миллисекунды)
  • метод ОсвободитьОбъект(COM-объект)
  • свойство АргументыКоманднойСтроки
  • метод ТекущийСценарий()
  • метод ПодключитьСценарий()

Подробнее о назначении этих методов и свойств можно прочитать в wiki проекта. Состав классов будет пополняться.

Отличия от стандартной библиотеки 1С

  • Из математических функций реализованы только Цел, Окр, Pow и Sqrt
  • Не реализованы строковые функции СтрЧислоСтрок, СтрПолучитьСтроку, СтрЧислоВхождений, ТРег
  • Не реализована функция форматирования строк Формат
  • Не реализована работа с типами (функции Тип и ТипЗнч)
  • Не реализовано динамическое выполнение кода функциями Вычислить и Выполнить
  • Не реализованы функции ДобавитьОбработчик, УдалитьОбработчик для обработки событий COM-объектов.
  • Не реализованы системные перечисления
  • Не поддерживается оператор Перейти и метки

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

Построение самостоятельного exe-модуля

1Script позволяет упаковать ваш скрипт в отдельный exe-модуль, который можно удобно распространять, не требуя установки самого 1Script на машину пользователя.

Для создания exe нужно запустить oscript.exe с ключом –make и указать имя входного скрипта и выходного exe.

Пример:

oscript.exe –make C:myscript.1scr D:program.exe

Файл C:myscript.1scr будет упакован в самостоятельный exe-шник и сохранен, как  D:program.exe.

Небольшая демонстрация

В качестве примера предлагаю вашему вниманию классическую игру «Змейка», написанную полностью на языке 1С. (исходник игры и сам exe можно скачать в прилагаемых файлах)

Системные требования

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

Стабильность текущей версии

На данный момент проект находится в активной разработке, поэтому, весьма вероятны ошибки и неточности в работе. Обо всех обнаруженных недостатках сообщайте любым удобным способом – в комментариях здесь, личным сообщением, в разделе Issues на странице проекта в bitbucket.

Обновление от 22.10.2014:

Дистрибутив обновлен до версии 1.0.7. Дальнейшее развитие проекта.

Обновлена и актуализирована вики проекта по адресу https://bitbucket.org/EvilBeaver/1script/wiki/Home

По традиции, исходники проекта открыты, сотрудничество приветствуется.

Спасибо за внимание.

91 Comments

  1. qwinter

    Неужели написать это было проще, чем «знакомому» выучить язык?

    Reply
  2. ivanov660

    Довольно хорошая идея, теперь «можно составить конкуренцию» компании 1С 🙂 Движок (плагин к браузеру) + браузер.

    Reply
  3. Evil Beaver

    (2) ivanov660, ну в чем же дело? Вам и карты в руки — берите исходники и вперед! Почему-то всем очень хочется «составить конкуренцию». Ну составляйте, в чем беда? Например мне это не надо. 1Script — это эксперимент, интересный в первую очередь мне лично. Ни про какую конкуренцию я не говорил.

    Reply
  4. asved.ru

    Однако 🙂

    Reply
  5. baton_pk

    плюс собрату по (не)счастью 🙂

    пишу такое же творение, только

    0) Код закрыт

    1) без привязки к .NET

    2) работает и под виндой, и под никсами (пробовал Ubuntu 12.04, 13.04, 14.04)

    3) возможность разработки и подключения модулей. Среди которых уже есть Xml, Yaml (JSON), Postgres в зачатке, COM-объекты (для винды), Gtk+ в зачатке.

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

    Для чего всё это? Да собственно для того же — у нас всяческие скрипты для обмена файликами крутятся на этом движке. Запилю сокеты и HTTP-сервер — будет ещё и система удалённого управления скриптами. А «конкуренцию 1С» — это чур, ребята…

    А, ещё забыл уточнить: у меня работают директивы препроцессора #Если клиент/сервер/скрипт/…

    Это позволяет при использовании одного и того же кода и в 1С, и в скрипте разделять логику исполнения.

    Reply
  6. baton_pk

    Ну ребяяяяят…

    А = Новый Массив(5);
    Сообщить(А.Получить(1));
    
    ScriptEngine.Machine.RuntimeException: Object method получить is not found
    в ScriptEngine.Machine.Contexts.ContextMethodsMapper`1.FindMethod(String name)
    в ScriptEngine.Machine.Contexts.ContextBase`1.FindMethod(String name)
    в ScriptEngine.Machine.MachineInstance.PrepareContextCallArguments(Int32 arg, IRuntimeContextInstance& context, Int32& methodId, IValue[]& argValues)
    в ScriptEngine.Machine.MachineInstance.ResolveMethodFunc(Int32 arg)
    в ScriptEngine.Machine.MachineInstance.MainCommandLoop()
    в ScriptEngine.Machine.MachineInstance.ExecuteCode()
    в ScriptEngine.Machine.MachineInstance.ExecuteModuleBody()
    в ScriptEngine.ScriptingEngine.<>c__DisplayClass1.<NewObject>b__0()
    в ScriptEngine.Machine.MachineInstance.StateConsistentOperation(Action action)
    в ScriptEngine.ScriptingEngine.NewObject(LoadedModuleHandle module)
    в ScriptEngine.HostedScript.Process.Start()
    Error detected. Exit code = 1
    Script completed: 16.06.2014 13:14:51
    Duration: 00:00:00.0002799

    Показать

    Reply
  7. Evil Beaver

    (5) baton_pk, Если GTK, то pure C, я правильно понимаю? А не затруднит в личку рассказать подробнее, для чего применяется и зачем именно свой движок, а не кросс-платформенный питон тот же?

    Reply
  8. Evil Beaver

    (6) baton_pk, да, метод «Получить» массива я не делал. Поленился. Зачем, если есть доступ по индексу?

    Reply
  9. baton_pk

    (8) для совместимости кода :).

    Reply
  10. Evil Beaver

    (9) baton_pk, Убедили, добавлю )

    Reply
  11. baton_pk

    Советую расширить набор тестов 🙂

    Разность = ‘20010102’ — ‘20010101’;
    Сообщить(Разность);
    
    ScriptEngine.Machine.RuntimeException: Conversion to Number is not supported
    в ScriptEngine.Machine.SimpleConstantValue.AsNumber()
    в ScriptEngine.Machine.MachineInstance.Sub(Int32 arg)
    в ScriptEngine.Machine.MachineInstance.MainCommandLoop()
    в ScriptEngine.Machine.MachineInstance.ExecuteCode()
    в ScriptEngine.Machine.MachineInstance.ExecuteModuleBody()
    в ScriptEngine.ScriptingEngine.<>c__DisplayClass1.<NewObject>b__0()
    в ScriptEngine.Machine.MachineInstance.StateConsistentOperation(Action action)
    в ScriptEngine.ScriptingEngine.NewObject(LoadedModuleHandle module)
    в ScriptEngine.HostedScript.Process.Start()
    Error detected. Exit code = 1
    Script completed: 16.06.2014 14:07:30
    Duration: 00:00:00.0002033
    

    Показать

    Reply
  12. Evil Beaver

    (11) baton_pk, О, как хорошо, что я вас встретил! ) Собственно, одному тестирование и не осилить. Надеюсь на сообщество. Оказывается, разность дат не сделал. Только Дата минус Число. Спасибо.

    Reply
  13. baton_pk

    Ещё косяк. Конструкция ?(,,) — это именно конструкция языка, а не функция с параметрами.

    Функция Ага()
    Возврат «Ага»;
    КонецФункции
    
    Функция Ошибка()
    ВызватьИсключение «Код не должен быть вызван!»;
    КонецФункции
    
    Сообщить(?(Истина, Ага(), Ошибка()));
    

    Показать

    ScriptEngine.Machine.RuntimeException: Код не должен быть вызван!
    в ScriptEngine.Machine.MachineInstance.RaiseException(Int32 arg)
    в ScriptEngine.Machine.MachineInstance.MainCommandLoop()
    в ScriptEngine.Machine.MachineInstance.ExecuteCode()
    в ScriptEngine.Machine.MachineInstance.ExecuteModuleBody()
    в ScriptEngine.ScriptingEngine.<>c__DisplayClass1.<NewObject>b__0()
    в ScriptEngine.Machine.MachineInstance.StateConsistentOperation(Action action)
    в ScriptEngine.ScriptingEngine.NewObject(LoadedModuleHandle module)
    в ScriptEngine.HostedScript.Process.Start()
    Error detected. Exit code = 1
    Script completed: 16.06.2014 14:58:51
    Duration: 00:00:00.0024617
    

    Показать

    Reply
  14. baton_pk

    Я смотрю, для чисел везде используется вещественный тип? Опасное дело.

    БешеноеЧисло  = 123456789123456789123456789123456789;
    БешеноеЧисло2 = БешеноеЧисло + 1;
    Сообщить(БешеноеЧисло — БешеноеЧисло2);
    
    Script started: 16.06.2014 15:11:10
    0
    
    Script completed: 16.06.2014 15:11:10
    Duration: 00:00:00.0000686
    
    Reply
  15. Evil Beaver

    (13)(14) baton_pk, про эти проблемы я знаю. По числам: сделано везде вещественное просто для упрощения и ускорения разработки. double инкапсулирован и наружу нигде не вылезает. Просто делать хорошее «Число», на мантиссах/порядках — не тот уровень проекта. Требует и знаний и усилий. Ощущаю у себя их нехватку в этом вопросе.

    Про «знак вопроса» — тоже знаю, сделал осознанно, опять же с целью ускорения. Как функцию его удобнее было скомпилировать.

    Проекту меньше месяца и пишется он, в основном, ночами. Поэтому, узкие моменты типа «знака вопроса» и недостающих малопопулярных методов у массива сознательно опущены. Есть много более насущных задач, которые нужно решить в первую очередь.

    Reply
  16. baton_pk

    (15) ну, в C# есть BigDecimal. А к своему я подумываю GMP прикрутить.

    PS.

    Вру, встроенного нету. Есть вот

    Reply
  17. Evil Beaver

    (16) baton_pk, я исходил из того, что задачи, требующие длинного матана и больших точностей довольно редки в сфере предполагаемой применимости.

    Кстати, как у вас с такими «Числами»?

    Reply
  18. baton_pk

    (17)

    Кстати, как у вас с такими «Числами»?

    Пока никак. Думаю прикрутить GMP и то, опционально. Длинные числа становятся нужны на стыке с базами данных: будет какое-нибудь поле Сумма типа Число(29, 2) и кури сиди…

    А так, согласен, в 99% случаев long и double — то, что надо.

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

    Reply
  19. CheBurator

    По-моему, еще Вася Душелов писал что-то аналогичное

    Reply
  20. Evil Beaver

    (19) CheBurator, идея витает в воздухе, так что, вероятно, и не только он.

    Reply
  21. JohnyDeath

    (19) CheBurator, да, мне тоже первым вспомнился он со своей последней идеей по встраиванию кода 1С в консоль.

    Reply
  22. EmpireSer

    Интересно, а почему ни кто не пытается саму 1С запустить «не стандартно»? Так, например, делает утилита «chdbfl.exe».

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

    Reply
  23. Evil Beaver

    (21) del

    Reply
  24. baton_pk

    (22) EmpireSer,

    1) сложно

    2) бессмысленно

    3) сложно

    Reply
  25. AlexanderKai

    Программа компилируется или внутри программы виртуальная машина?

    Reply
  26. Evil Beaver

    (25) AlexanderKai, если я правильно понял, вы спрашиваете про компиляцию в машинный код? Нет, exe — это исполняющий модуль (виртуальная машина), в который вложен байткод скрипта. Хотя, в конечном итоге CLR все равно компилирует все это в машинный код, так что ответ «и да и нет» )

    Reply
  27. AlexO

    (22) EmpireSer,

    саму 1С запустить «не стандартно»?

    А с чего CHDBFL вдруг стала запускать нестандартно? Она просто раскладывает CD на таблицы и проверяет их отдельно в темповом файле. И абсолютно неприменима к SQL, т.к. структура таблиц совершенно иная.

    (0)ничего не понял, но причем тут 1С, если, как обычно, «Shell = Новый COMОбъект(«WScript.Shell»);»??

    WScript и запускает эти ваши консольные и прочие приложения, а кто его вызывает — и ему, и мне неинтересно.

    А уж про «конкурент 1С» (2) писать на эту тему… это человек вообще не вникал ни капли, поняв еще меньше моего ))

    Reply
  28. Evil Beaver

    (27) AlexO, дорогой, поскольку, вы известный трололо, то и отвечать вам не вижу смысла 😉

    Reply
  29. powerpc

    Извините великодушно, НО:

    Как можно писать в 1С конструкции типа:

    Shell = Новый COMОбъект(«WScript.Shell»);

    ПапкаПараметров = Shell.ExpandEnvironmentStrings( «%APPDATA%» );

    если «Нет времени учить JScript или VBScript» ?????

    То же самое можно написать в текстовом файле и скомпилировать существующими утилитами в exe.

    Reply
  30. baton_pk

    (27)(28)

    А тут я согласен. Если уж это 1С, а не Russian VBScript, то должны быть всем нам привычные команды: ПереместитьФайлы, УдалитьФайл и подобные.

    Иначе какой смысл во всех этих коллекциях, если с WSH работа всё равно идёт по большому счёту с простыми типами. Встроенный функционал по-любому надо расширять.

    Reply
  31. Evil Beaver

    (29)(30) baton_pk, никто не спорит, расширять надо. Уже есть ЧтениеФайлов и Консоль (специально ради «змейки»). Стандартные 1С-овские вещи работы с файлами обязательно будут. На данный момент решена задача минимум — сама возможность писать скрипты. Для выхода во «внешний мир» уже сейчас можно применять COM.

    Я надеюсь привлечь разработчиков к самой возможности писать такие скрипты, заинтересовать и подключить к разработке. Расширение библиотеки классов это важная задача, но я пока что один, много не успеть.

    Уже сейчас я доделываю расширение к Снегопату. Надеюсь, что можно будет писать плагины к снегопату не на JS, а на близком и родном 1С. Уже сейчас оно работает, хоть и пока очень сыро.

    И это уж вы, powerpc, простите великодушно, но я нигде не сказал, что это решение промышленного уровня. Но оно имеет потенциал стать таковым, это уже немало.

    Приведенный пример с архивацией баз — рабочий, т.е. уже может применяться. Прикладные классы разрабатывать и подключать к системе не сложно. Присоединяйтесь!

    Reply
  32. Ivon

    Честно-говоря, я вообще не вижу перспективы данной разработки. Кроме 1С еще программлю на C# и когда-то программил на Perl и этих языков мне хватало для того, чтобы сделать все необходимые операции. Имхо, изобретение велосипеда — не лучший вариант потратить время.

    Reply
  33. zarius

    Работа, конечно, проделана громаднейшая — автору респект, но именно «консольные exe-приложения» в данном проекте, имхо, представляют чисто академический интерес.

    Не проще ли воспользоваться тем же AutoIt? Разобраться можно за 5 минут, а возможностей там…

    Reply
  34. baton_pk

    (32) Ivon, ну, теперь будет хватать одного 1С, без перлов и шарпов :):)

    Reply
  35. v77

    🙂 Моя тема. Тоже писал и интерпретатор языка 1С и компилятор из 1с в Паскаль. Не помню где это всё лежит.

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

    П = 500.48;

    Для а = 1 по 10000000 цикл

    П = П + 500.48;

    КонецЦикла;

    а на моём вариантном асме за 80 миллисекунд

    InitInt $1

    loop:

    Ldd П, 500.48

    Jmp ($1 >= 10000000) end_loop

    Add П,500.48

    IncInt $1

    Jmp loop

    end_loop:

    Автору успехов! Плюсую!

    Reply
  36. baton_pk

    (35) v77, о, ещё один в нашем клубе.

    компилятор из 1с в Паскаль

    Это транслятором зовётся, а не компилятором 🙂

    Не помню где это всё лежит.

    Для того и придуманы гитхаб с битбакетом 🙂

    Пока в зачатке, но скорость работы неплохая

    Вы сборщик мусора прикрутите и обработку исключений — там и посмотрим на быстродействие 🙂 (и поиск HASP-ключа ещё 😀)

    Reply
  37. v77

    (36) baton_pk,

    «Это транслятором зовётся, а не компилятором :)»

    ой, да какая разница.

    Сборщик мусора это такая фигня, которая сжирает всю память, а потом отдает по маленьку и жутко всё тормозит? Не, нафиг он нужен. И без него хорошо. А обработка исключений на скорость слабо влияет.

    Reply
  38. baton_pk

    (37) v77,

    Сборщик мусора это такая фигня, которая сжирает всю память, а потом отдает по маленьку и жутко всё тормозит? Не, нафиг он нужен.

    Не совсем. В общем случае это штуковина, которая определяет, что память более не используется, и освобождает её.

    Штука нужная, если предполагается, что программа постоянно висит в памяти. Для программ на один проход и в правду можно его не использовать в большинстве случаев.

    Reply
  39. v77

    (38) baton_pk,

    «Штука нужная» ну иногда и нужная, а в основном время она жрет. я бы просто сделал функцию УдалитьПотом(Массив), чтобы освобождать память от больших объектов не сразу, а потом, когда программа ничего не делает. А всякую мелочь убивать сразу в конце процедуры и не париться. Т.е. такой ручной сборщик мусора.

    Reply
  40. baton_pk

    (39) v77,

    ну так это и есть сборщик мусора. Сборка мусора — тема настолько широкая и толстая, что нельзя вот просто так взять и сказать «это сейчас удалить, это потом».

    Представим, что у нас 2 гига свободной памяти:

    А = Новый МассивНаПолтораГига;
    РаботатьСМассивом(А);
    А = Неопределено; // <- тут его по-любому надо грохнуть
    Б = Новый МассивНаПолтораГига; // чтобы хватило памяти под этот
    

    к тому же это мы рассматриваем только память. Есть ещё другие ресурсы: сеть, файлы.

    Ну а про ручной сборщик: добро пожаловать в БДСМ клуб! Делать языки с управляемым кодом, чтобы ещё и мусор руками собирать 🙂

    Reply
  41. v77

    (40) baton_pk,

    А = Неопределено; //

    и 1с это сразу освободит или отложит? Я так думаю, что она отложит. Уж больно часто в 1с памяти не хватает.

    Reply
  42. baton_pk

    (41) v77,

    пол-сообщения у меня съелось тут почему-то.

    и 1с это сразу освободит или отложит? Я так думаю, что она отложит.

    Проверил — освободит.

    И дело тут не в том, как 1С это сделает, а в том, что сделает оно это само, без ручных УдалитьТоДаСё.

    Reply
  43. v77

    (42) baton_pk,

    Проверил — освободит.

    это хорошо. надо запомнить.

    Reply
  44. Evil Beaver

    (43) v77, надо не запомнить, а почитать матчасть. 1С использует подсчет ссылок. Присвоение переменной другого значения очищает память, если нет других ссылок на данный объект. Это значит, что проблема циклических ссылок существует и ее надо учитывать.

    И, как заметил baton_pk она делает это сама, без ручных очищений. Это очень хорошо, т.к. внезапный бросок исключения может увести исполнение кода в другое место и не дойдет до вашего «УдалитьПотом».

    М = Новый Массив;
    М.Добавить(1);
    Сообщить(М[4]); // нечаянно вышли за границу  массива
    УдалитьПотом(М); // сюда не дойдет.
    
    Reply
  45. v77

    (44) я не против того, чтобы память освобождалась автоматически. Я за то, чтобы память освобождалась автоматически сразу, при выходе из процедуры, а не когда сборщик мусора захочет. А то 1с жрет память гигабайтами непонятно на что и меня это не устраивает.

    Reply
  46. artbear

    подписался

    Reply
  47. baton_pk

    (45) v77,


    память освобождалась автоматически сразу, при выходе из процедуры, а не когда сборщик мусора захочет

    Ненене. Пусть сборщик мусора сам решает, когда чего чистить. Это его работа.

    Если память утекла, это значит не то, что сборщик её не освободил вовремя, а то, что он в принципе не может её освободить. А тут уже не имеет значения, когда он пытается это сделать. Зависшие ссылки, ошибки платформы — всякое может быть.

    Reply
  48. Evil Beaver

    (45) v77, ну во-первых, идея сборщика мусора не рождается на пустом месте. Она появляется, когда существующие решения не устраивают.

    Подсчет ссылок имеет ряд недостатков, в том числе, упомянутые циклические ссылки.

    Во-вторых, какая разница сколько памяти съел сервер 1С? И чем вы это измеряете, диспетчером задач? Есть такой термин: Task Manager Syndrome, загуглите, это интересно. Если система не испытывает давления по памяти, пусть программы съедают столько, сколько им нужно, вам жалко что-ли?

    Ну и, в-третьих, если вас не устраивает, как работает сервер 1С, то вот: все в ваших руках.

    Reply
  49. akomar

    Подписался на тему, (заинтересовало обсуждение о сборщиках мусора) 🙂

    Reply
  50. baton_pk

    Запилил поддержку OneScript в Geany.

    Чтобы скрипт запускался из редактора, пропишите путь к OneScript в %PATH% или непосредственно в пути в настройках программы.

    Тестил под WinXP и под Win7.

    Reply
  51. Evil Beaver

    (50) baton_pk, прикольно, а если в двух словах, то как выглядит выполнение кода? Ну в geany я набью код, а дальше что там?

    Reply
  52. baton_pk

    (51) просто нажать кнопку «Выполнить» и он тупо выполнит команду «oscript.exe <мойфайл.1src>».

    На данный момент это пока всё 🙂 — подсветка да встроенная команда выполнения. Потом лексер прикручу да пошаговое выполнение.

    Reply
  53. p1l1gr1m

    Автору респект за труды!

    Reply
  54. alexqc

    (3) А где исходники взять :)?

    Reply
  55. alexqc

    (3), (54) Все, нашел

    Reply
  56. alexqc
     аа= ложь или «111»;
    Сообщить(аа);
    
    аа= Истина И «111»;
    Сообщить(аа);
    
    

    выведет «111», 1С же в этом случае ругается. В принципе вариант имеет право на существование, но т.к. есть ограничения по конверсии в тип булево, стоит все же сделать как в 1С — правильнее будет локализовывать ошибки.

    аа= Ложь или «111»;
    бб= Не аа; //Ошибка вылезет тут, хотя реально строкой выше
    
    
    аа= «111» и Истина; //ошибка
    аа= Истина и «111»; //ошибки нет, хотя формально от предыдущей строки не отличается. При чем результат выражения таков, что иначе как бредом и не назовешь.
    
    

    Показать

    Reply
  57. alexqc
    А=5;
    Для ш=1 по А Цикл
    Сообщить(ш);
    А=4;
    КонецЦикла;

    Пройдет цикл 1..4, в то время как в 1С — 1..5. Это тянется еще с 7ки (а может и раньше) — граница цикла вычисляется один раз при старте цикла, и потом не меняется.

    Reply
  58. Evil Beaver

    (56)(57) alexqc, если не сложно, зарегистрируй, пожалуйста, ошибки в Issues на bitbucket?

    Reply
  59. AlexanderKai

    (57) alexqc,

    Кстати очень неудобная фича. Иногда не хватает гибкости оператора for как в Си.

    Reply
  60. BorovikSV

    (59) AlexanderKai, для любых фич есть WHILE.

    Reply
  61. Pawlick

    Очень, очень интересная вещь. Уважение автору.

    Reply
  62. alexqc

    (59) AlexanderKai, как сказать, как сказать… Иногда удобнее именно так (например, когда в цикле до количества объектов в коллекции добавляются объекты в эту самую коллекцию), кроме того, хоть чуть-чуть но это оптимальнее (нет необходимости вычислять границу N раз). Вот чего реально в 1С-for не хватает — это цикла «вниз».

    Reply
  63. baton_pk

    Вчера получилось собрать под Ubuntu 14.04: собралось всё, кроме TestApp и расширения для снегопата.

    Reply
  64. Evil Beaver

    (63) baton_pk, Ну так понятно: TestApp — это WPF, его под Mono нету. А расширение Снегопата — вообще сплошной COM.

    Reply
  65. v77

    Чота вычисляет как-то неправильно

    раз = 100 + 100 + 20 * 100 / 2 — 18 + 45698 * 45789 / 16 — 500 — 800 * 19;

    сообщить(раз);

    выдает 130763475.25

    в Delphi, 1с и моей поделке выдает 130764589.625

    Reply
  66. Evil Beaver

    (65) v77, посмотрю, спасибо.

    Reply
  67. baton_pk

    (64)

    не, снегопат не собрался, потому что у меня Managed C++ под Mono нет. То есть, я в принципе не пытался его собрать.

    Reply
  68. Evil Beaver

    (67) baton_pk, ну я в этом не силен. В Mono пробовал только Hello World-ы писать 🙂

    Reply
  69. v77

    П = 500.48;

    Для а = 1 по 10000000 цикл

    П = П + 500.48;

    КонецЦикла;

    Сообщить(П);

    выдаст в 1с

    5004800500.48

    вместо

    5004800499.98169

    это вопрос религии, но если делать совместимо с 1С, то надо использовать какой нибудь Currency вместо Double

    Reply
  70. Evil Beaver

    (69) v77, как раз «делать совместимо» задачи нет. Изначально я ставил задачу себе — рабочая виртуальная машина с интерпретацией языка 1С, при этом, реализованная с минимальными затратами. Насколько мне хватает понимания — в 1С используется длинная арифметика с представлением чисел в виде порядка/мантиссы. Я ничего такого не планировал, а «урезал» на проектном уровне до простого double. Числа в OneScript — это double среды CLR. Я не планировал делать его таким, как в 1С, ибо не имею достаточно знаний в этом вопросе.

    Reply
  71. BorovikSV

    (70) Я реализовал длинную арифметику самостоятельно.

    Сначала нашел рабочие исходники — оказались слишком неуклюжими. Производительность крайне страдала.

    Задал себе вопрос: Че я не программист что ли?

    Убил день на основные операции + неделю на операцию деления (раз 5 переписывал алгоритмы деления, т.к. не проходили тесты, то одни то другие).

    Попробуй — интересная задача.

    P.S. Мой язык Delphi

    Reply
  72. Evil Beaver

    (71) BorovikSV, вопрос-то в другом. Оно вам реально надо? Вот что прям, действительно, вот надо считать большие числа консольными скриптами на языке 1С? А под какие задачи?

    Reply
  73. JohnyDeath

    А скрипт может принимать параметры? Если да, то как их обработать внутри скрипта?

    Например вот такое:

    oscript.exe prinmessage.os «Привет мир»

    Reply
  74. Evil Beaver

    (73) JohnyDeath, начиная с версии 1.0.5 — может.

    Для Каждого Аргумент Из АргументыКоманднойСтроки Цикл
    Сообщить(Аргумент);
    КонецЦикла
    
    Если АргументыКоманднойСтроки[0] = «kill-all-humans» Тогда
    УбитьВсехЧеловеков();
    КонецЕсли;
    Reply
  75. JohnyDeath

    (74) отлично! Спасибо.

    (на битбакете вики что-то практически пустая)

    Reply
  76. Evil Beaver

    (75) JohnyDeath, она переживает второе рождение) Я ее переписываю, пока не закончил.

    Reply
  77. BorovikSV

    (72) надо или не надо — тут не абсолютно причем. Тут все просто: либо ваши числовые значения урезанные, либо нет.

    Можно получить сюрпризы от double в самый неподходящий момент. И вовсе не обязательно при этом считать песчинки в мировом океане.

    Reply
  78. Evil Beaver

    (77) BorovikSV, Видимо, я знаю меньше, чем вы. Какие наиболее распространенные сюрпризы можно получить от double, которые нельзя получить от неограниченного числа? Кроме переполнения других сюрпризов не знаю.

    Reply
  79. v77

    (78) BorovikSV наверное намекает на типа такого:

    Результат = 1;

    Для а = 1 по 10 цикл

    Результат = Результат — 0.1;

    КонецЦикла;

    Сообщить(Результат);

    В 1С Результат будет равно 0

    Reply
  80. Evil Beaver

    (79) v77, Спасибо. Но это не отменяет моего непонимания этой темы. К сожалению) Буду совершенствоваться.

    UPD. Прочитал про double и ужаснулся. Оказывается, ему в принципе нельзя доверять, не округлив до конкретной точности.

    Это в корне меняет все дело. Думаю, что надо будет заменить на BigDecimal, который выше предложил baton_pk.

    Reply
  81. BorovikSV

    (80) Приведите ссылки про Double, чтобы другие тоже ужаснулись, и сделали выводы 🙂

    Reply
  82. Evil Beaver

    (81) BorovikSV,

    http://social.msdn.microsoft.com/Forums/vstudio/en-US/921a8ffc-9829-4145-bdc9-a96c1ec174a5/decimal-vs-double-difference?forum=csharpgeneral

    Там ближе к середине переписке будет:

    The fundamental difference is that the double is a base 2 fraction, whereas a decimal is a base 10 fraction.

    double stores the number 0.5 as 0.1, 1 as 1.0, 1.25 as 1.01, 1.875 as 1.111, etc.

    decimal stores 0.1 as 0.1, 0.2 as 0.2, etc.

    The double cannot store something like 0.3 as a plain binary fraction, so i think it uses an approximation

    И еще вот:

    Doubles use Floating Point storage in base 2, where as the Decimal stores the information in base 10.

    So, for example, 2.25 as a decimal would be stored as 225 * 10 #k8SjZc9Dxk -2 (underlined numbers are actually stored) or some variation thereof.

    The double would store 1001 * 2 #k8SjZc9Dxk -10 (underlined numbers are actually stored and they are in base 2).

    You can think of integer binary numbers as each digit as having a power of two, i.e.

    128 64 32 16 8 4 2 1

    for a floating point number, you just need to extend that to negative powers of two as well, i.e.

    16 8 4 2 1 1/2 1/4 1/8 1/16

    or

    16 8 4 2 1 .5 .25 .125 .0625

    Some of the implications:

    In my example I picked a number that is easily represented in binary format, but some numbers that are short/simple base 10 fractions are very long, if not irrational, binary fractions. This means that when using the double the number can sometimes be off from what you would expect

    Показать

    Короче, говоря, 0.1 в double на самом деле хранится, как 0.10000000000000001, причем этот хвост зависит от конкретного значения. Никогда нельзя сказать точно — чему равно значение double. Можно сказать, что «double имеет значение X с точностью до M знаков»

    Как-то так я это понял.

    Reply
  83. baton_pk
    Можно сказать, что «double имеет значение X с точностью до M знаков»

    Дааа, старая добрая школьная информатика! Паскаль, олимпиады и вот такое:

    const double eps = 0.001;
    …
    if abs(x — y) < eps then
    … x равно y с точностью до eps
    

    За `x = y` можно было и подзатыльника схватить от препода.

    Reply
  84. Evil Beaver

    (83) baton_pk, не у всех были столь эффективные преподы. Нам преподавали С++ весьма посредственно. Практически все что в нем знаю, изучил методом тыка. А в школе у нас был Бейсик на БК0011. Там не было double.

    Reply
  85. adapter

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

    Многие программеры 1С не сталкиваются с админскими задачами, поэтому наверное и отношение такое пессимистическое.

    А вот попробуй например из базы 1С взять инфу о пользователях и обновить платформу только на этих компах, да еще когда и админского доступа у пользователей нет (т.е. штатными средствами 1С никак). Хорошо когда конторка маленькая. А если 1000 компов, кто то в отпуске, командировке. А обновить надо только у 20 например?

    Да много чего еще хорошего можно сделать. Фишка в том что интегрируются возможности 1С и данные из баз с админскими задачами. Я сталкивался, знаю что к чему. Пришлось писать свою глобальную вещь на 1С, которая и админские задачи решает. Например регламентные задания на 1С простукивают сеть и компы по сокетам, wmi, ping и собирает из этого актуальную базу компов в 1С, далее по ним удаленное управление, пакетное обновление программного обеспечения ну и кучу всего.

    Reply
  86. Evil Beaver

    (85) adapter, ну вот, а теперь все это можно скопировать в текстовые файлы скриптов и запускать быстро, без оверхеда в виде платформы. Например, автоматически по расписанию или еще как-то. Т.е. теперь это честный «админский» скриптинг, но на понятном языке программирования.

    Reply
  87. baton_pk

    (86)

    теперь это честный «админский» скриптинг

    вот на днях применил не «по-админски» 🙂 Сделал скрипт, который по COM-соединителю запускает базу, берёт текущие продажи и по ADODB выгружает во внешнюю систему в головной офис. Осталось переделать, чтобы вместо COM-соединения с 1С данные брались запросом прямо из SQL и куча головной боли долой!

    Reply
  88. fixin

    (1) кстати, согласен, VBS практически 1:1 как 1С, но может быть тру-1сникам и будет полезно.

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

    Так что имхо — ненужный бантик. Но плюсую.

    Reply
  89. Serg O.

    самый простой пример для начала…

    Привет мир! ( Hello World! )

    делается 1 строкой… и цвет можно легко менять

    и БОЛЬШОЕ спасибо за компилятор и window-s консольку…

    в ней ещё удобнее стало работать — «стандартная» раскраска

    Reply
  90. oleg-x

    (82) Теперь стало понятен один глюк. Делал запрос к другой базе через COMобъект, так вот некоторые суммы переносились как 0.000000000000000001

    И было не понятно откуда эта 1 лезет. Теперь ясно 🙂

    Reply
  91. Evil Beaver

    (89) Эти инструменты устарели, а консолька вообще никогда не предназначалась для написания кода. Она отладочная, для внутренних тестов движка.

    Вот статьи по серьезной разработке на 1Script:

    https://infostart.ru/public/687869/

    https://infostart.ru/public/791568/

    https://infostart.ru/public/540284/

    https://infostart.ru/public/699642/

    Reply

Leave a Comment

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