Полезный код для программистов 1С (часть 1). Управление свойствами элементов формы. Хранение копии данных реквизитов

У каждого программиста за время работы накапливается полезный инструментарий, которым он привык пользоваться. Естественно и у меня он тоже имеется. И вот решено было немного поделиться с сообществом. Возможно идеи не новые. Более того, допускаю, что реализованы они не самым оптимальным образом. Но ведь для этого сообщество и существует, чтобы делиться с ним, получая обратную связь.

У каждого программиста за время работы накапливается полезный инструментарий, которым он привык пользоваться. Естественно и у меня он тоже имеется. И вот решено было немного поделиться с сообществом. Возможно идеи не новые. Более того, допускаю, что реализованы они не самым оптимальным образом. Но ведь для этого сообщество и существует, чтобы делиться с ним, получая обратную связь.

Содержание

Управление видимостью, доступностью и просмотром реквизитов формы

Преамбула. Еще в бытность работы в 7.7, а далее и в первых конфигурациях на 8.х совершенно точно не нравились процедуры и функции вроде "УстановитьВидимость" или "УстановитьДоступность" и т.п. В них собирались все элементы, по различным условиям устанавливалась видимость. Как правило в них условия выставлялись по бизнес-логике редактирования документа, например проверка по видам операций, различным условиям заполненности и т.д. В итоге один и тот же элемент мог встречаться несколько раз и конечные условия "почему он виден или доступен" приходилось вникать во всю логику. Но не сразу пришло понимание, как должно быть, как будет удобно. Были различные варианты. Но вот некоторое время назад, мы совместно с нашей командой остановились на представленном ниже варианте.

Существует основная процедура "УстановитьУсловноеОформление" (неудачное имя для метода, понимаю, но увы уже много кода "наделано" руки не дойдут изменить его везде). В качестве параметров метода выступает: ЭтотОбъект — т.е. сама управляемая форма в которой метод вызывается и ИменаРеквизитов — список имен (не обязательно) через "," для которых необходимо выполнить настройку видимости, доступности, просмотра или других свойств. При этом, есть возможность как создать произвольный набор элементов, так и не передавать список вовсе. В таком случае работать будет следующим образом:

  • НаборЭлементов — любое произвольное имя для набора элементов формы.
    Например: при изменении вида операции надо изменить видимость множества элементов формы. Для этого можно передать список имен этих элементов, но согласитесь, вызов метода может быть из нескольких мест, а потом найти и поправить все не факт что получится верно. Поэтому создается имя для набора, например: РеквизитыВидОперации. Далее в методе "УстановитьУсловноеОформлениеРеквизита" создается проверка условия и вызов метода для каждого из элементов входящих в набор. Таким образом, достаточно вызвать УстановитьУсловноеОформление(ЭтотОбъект, "РеквизитыВидОперации") и все зависимые элементы будут настроены. НО (повторюсь): можно указать и весь список элементов по отдельности.
  • Пустое имя реквизита — в таком случае настроены будут все элементы формы
&НаКлиентеНаСервереБезКонтекста
Процедура УстановитьУсловноеОформлениеРеквизита(Форма, Обработано, знач ИмяРеквизита)

Если НЕ Обработано.Найти(ИмяРеквизита) = Неопределено Тогда
Возврат;
КонецЕсли;
Обработано.Добавить(ИмяРеквизита);

Элементы    = Форма.Элементы;
Объект        = Форма.Объект;

#Область Наборы

Если ИмяРеквизита = "Реквизиты" ИЛИ ПустаяСтрока(ИмяРеквизита) Тогда
УстановитьУсловноеОформлениеРеквизита(Форма, Обработано, "Реквизит1");
УстановитьУсловноеОформлениеРеквизита(Форма, Обработано, "Реквизит2");
КонецЕсли;

#КонецОбласти

#Область Элементы

Если ИмяРеквизита = "Ответственный" ИЛИ ПустаяСтрока(ИмяРеквизита) Тогда
ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы,
"Ответственный", "ТолькоПросмотр", ЗначениеЗаполнено(Объект.Ответственный));
КонецЕсли;

#КонецОбласти

#Область ТабЧасть_Имя

Если ИмяРеквизита = "ИмяТабличнойЧастиОтветственный" ИЛИ ПустаяСтрока(ИмяРеквизита) Тогда
ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы,
"ИмяТабличнойЧастиОтветственный", "ТолькоПросмотр", ЗначениеЗаполнено(Объект.Ответственный));
КонецЕсли;

#КонецОбласти

#Область Команды

Если ИмяРеквизита = "КомандаЗаполнить" ИЛИ ПустаяСтрока(ИмяРеквизита) Тогда
ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы,
"ТаблицаФормыЗаполнить", "Видимость", НЕ Объект.Проведен);
КонецЕсли;

#КонецОбласти

КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура УстановитьУсловноеОформление(Форма, знач ИменаРеквизитов = "")

Если ТипЗнч(ИменаРеквизитов) = Тип("Строка") Тогда
Если ПустаяСтрока(ИменаРеквизитов) Тогда
МассивИмен = Новый Массив;
МассивИмен.Добавить("");
Иначе
МассивИмен = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ИменаРеквизитов, ",");
КонецЕсли;
ИначеЕсли ТипЗнч(ИменаРеквизитов) = Тип("Массив") ИЛИ ТипЗнч(ИменаРеквизитов) = Тип("ФиксированныйМассив") Тогда
МассивИмен = ИменаРеквизитов;
Иначе
Возврат;
КонецЕсли;

//Форма.ТолькоПросмотр = (Форма.СостоянияЗаблокировано.Найти(Форма.СведенияОЗаявкеСостояние) <> Неопределено);

Обработано = Новый Массив;
Для Каждого ИмяРеквизита Из МассивИмен Цикл
УстановитьУсловноеОформлениеРеквизита(Форма, Обработано, СокрЛП(ИмяРеквизита));
КонецЦикла;

КонецПроцедуры

// как использовать
УстановитьУсловноеОформление(ЭтотОбъект, "ИмяРеквизита");

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

Проверка изменений значений реквизитов формы

Преамбула. Регулярно при изменении значений реквизитов формы необходимо выполнять те или иные действия. Часто приходится с клиента вызывать сервер. В таком случае, необходимо минимизировать вызовы. Да и вообще иногда надо проверить какое значение имел реквизит, чтобы выдать предупреждение о выборе некорретного значения и вернуть старое значение. Обычно для таких целей создают реквизиты формы куда записывают текущее значение и "ПриИзменении" проверяют выбранное значение и текущее, выполняют обработку или возвращают старое значение. Меня лично это крайне напрягает, более того когда надо проверку повесть на множество реквизитов, тогда набор реквизитов формы становится невыносим большим. А чем больше реквизитов, тем больше вероятность ошибки в будущем.

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

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

// Описание использования
//
//    1. Разместить команды из процедуры ИнициализацияФормы в соответствующую по смыслу процедуру формы (или вызвать метод из ПриСозданииНаСервере, ПриЧтенииНаСервере)
//    2. Добавить все сохраняемые реквизиты в процедуре СнятьКопиюОбъекта
//    3. Назначить обработчики ПриИзменении на сохраняемые реквизиты (см. ИмяРеквизитаПриИзменении)
//

&НаСервере
Процедура ИнициализацияФормы()

РаботаСФормами.СоздатьРеквизитХраненияКопииДанныхФормы(ЭтаФорма);

// прочие обработки
<?>

СнятьКопиюОбъекта(ЭтаФорма);

КонецПроцедуры

&НаКлиенте
Процедура ИмяРеквизитаПриИзменении(Элемент)
Если СравнитьСКопиейОбъекта(ЭтаФорма, "Объект.ИмяРеквизита") Тогда
Возврат;
КонецЕсли;

// прочие обработки

СнятьКопиюОбъекта(ЭтаФорма);
КонецПроцедуры

#Область СлужебныеПроцедурыИФункции_КопияДанныхФормы

&НаКлиентеНаСервереБезКонтекста
Процедура СнятьКопиюОбъекта(Форма)
МассивРеквизитов = Новый Массив;
МассивРеквизитов.Добавить("Объект.Дата");
МассивРеквизитов.Добавить("Объект.Организация");
МассивРеквизитов.Добавить("ИмяРеквизита");

РаботаСФормамиКлиентСервер.СкопироватьДанныеФормы(Форма, МассивРеквизитов);
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция СравнитьСКопиейОбъекта(Форма, ИмяРеквизита)
Возврат РаботаСФормамиКлиентСервер.СравнитьСКопиейДанныхФормы(Форма, ИмяРеквизита);
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ЗначениеИзКопииОбъекта(Форма, ИмяРеквизита)
Возврат РаботаСФормамиКлиентСервер.ЗначениеИзКопииДанныхФормы(Форма, ИмяРеквизита);
КонецФункции

#КонецОбласти

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

Послесловие

На самом деле оригинального и сверхумного ничего в представленном коде нет, да и быть не может. Что придумал один человек, второй всегда повторит. Я с удовольствием выслушаю критику и внесу изменения. Надеюсь, код подкажется полезным кому-либо. И кстати, может уже кто-то трудится над созданием репозитория с "полезным" кодом? Используйте на здоровье, модифицируйте и т.д.
Версионирование данных инструментов на текущий момент не ведется. Пока не вижу смысла. Жизнь покажет.
На картинке изображен детский набор инструментов "Fisher-Price Disney’s Handy Manny Talking Tool Box". Вдруг кому интересно )))).

78 Comments

  1. vandalsvq

    (1) ну это понятно, в таком случае обработка изменения уже забота программиста

    Reply
  2. pm74

    (2) я просто имел в виду , было бы неплохо , если бы 1с случае любого локального события формы , генерировало какое то событие изменения данных формы которое можно было отловить

    Reply
  3. Xershi

    (3) Флаг модифицированность для этого!

    Reply
  4. pm74

    (4) и ? в какой момент его считывать ?

    Reply
  5. spacecraft

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

    Reply
  6. pm74

    (6) автор правильно указал на проблему , если вы меняете реквизит у вас нет старого значения реквизита ,даже если он фактически не изменился генерируется событие при изменении

    Reply
  7. spacecraft

    (7) не ответили на вопрос. Какое событие нужно отлавливать отдельно? Если меняете программно реквизит, значит можете предусмотреть обработку логики изменения этого реквизита.

    Reply
  8. Xershi

    (5) какой алгоритм заложите такой и будет!

    Reply
  9. tsukanov

    (1) Попробуйте это:

    Процедура УстановитьЗначениеИнтерактивно(Значение, Элемент, Форма)
    Перем ВладелецФормы, ЗакрыватьПриВыборе;
    
    ВладелецФормы = Форма.ВладелецФормы;
    ЗакрыватьПриВыборе = Форма.ЗакрыватьПриВыборе;
    
    Форма.ВладелецФормы = Элемент;
    Форма.ЗакрыватьПриВыборе = Ложь;
    
    Форма.ОповеститьОВыборе(Значение);
    
    Если Форма.ВладелецФормы = Элемент Тогда
    Форма.ВладелецФормы = ВладелецФормы;
    КонецЕсли;
    
    Если Не Форма.ЗакрыватьПриВыборе Тогда
    Форма.ЗакрыватьПриВыборе = ЗакрыватьПриВыборе;
    КонецЕсли;
    
    КонецПроцедуры // УстановитьЗначениеИнтерактивно()

    Показать

    ps Написал по памяти. Не проверял. Мог косякнуть.

    pps Это типа универсальная общая процедура. Подходит не для всего конечно

    Reply
  10. the1

    (10) Что за удивительная абстрактная фигня?

    Reply
  11. tsukanov

    (11) Эта фигня делает то, что хочет автор первого коммента. Я ответил на ваш вопрос?

    Reply
  12. tormozit

    (10) Лучше брать эту процедуру из модуля ирОбщий.ИнтерактивноЗаписатьВЭлементУправленияЛкс инструментов разработчика. https://infostart.ru/public/16985/

    Reply
  13. tsukanov

    (13) Да, ваш вариант лучше.

    Reply
  14. azhilichev

    (3) Как раз наоборот это правильное поведение. Не зря ПриОткрытии(), ПриИзменении() и т.п. называются обработчиками событий.

    Reply
  15. protexprotex

    Было бы полезным если бы фирма 1С сделала как в C++ (например как в C++) — отделила бы определение функции от самой функции. Т.е. типа h и cpp файлов. По моему, удобно было бы.

    Reply
  16. Vovan1975

    (17) ну ну. Удобно ога. Добавил параметр в процедуру и незабудь еще в объявлении его зафигачить.

    Было это на 7.7, никакого удобства нет

    Reply
  17. KapasMordorov

    (17)

    Это в 7.7 было.

    Reply
  18. protexprotex

    (18) На 7.7. это было сделано через клавиатуру :-). h — файлы нужны для экспортируемых функций — т.е. можно было хранить объявления функций в одном файле, а сами функции — в другом. И к своему проекту подсоединять только h — файлы — и если Вы используете функцию, то она только и компилится в проекте -> проект меньше и работает быстрее. А 1С при открытии модуля все это хозяйство переводит в байт — код -> вывод — ускорение было бы работы 1С.

    Reply
  19. Dementor

    (17)

    Т.е. типа h и cpp файлов. По моему, удобно было бы.

    Ага, так это удобно, что мои знакомые программисты сишники на небольших проектах все фигачат сразу в *.hpp файлы 🙂

    (20)

    А 1С при открытии модуля все это хозяйство переводит в байт — код -> вывод — ускорение было бы работы 1С.

    Ради ускорения на незаметные глазу микросекунды вы предлагаете увеличить время на работу программиста и расширить возможности допустить ошибки?

    Я тут на днях решил таки легендарного Брукса почитать. Так он в своей статье про использование современных ЯП (на те годы это были APL, Algol, Fortran и прочие) говорит, что не смотря на некоторое увеличение времени на компиляцию все же, в общем итоге, выгодно использовать ЯП высокого уровня, так как это в разы экономит программистам их время, уменьшает затраты на разработку, а оптимизацию выполнения может на себя взять компилятор. Это я к чему вспомнил? Главное удобство программиста при разработке, а в продакшине (сервер или файловая уже не важно) все равно будет крутится закешированный байт-код.

    Reply
  20. protexprotex

    (21)

    Это не просто удобно. Это нужно. Т.к. если Вы захотите импортировать в свой проект чужие наработки, то hpp файлы не импортируют, а импортируют именно h — файлы — заголовки->lib — ы и т.д. А то что знакомые сишники все hpp файлы «фигачат», так это не относится к языку программирования. Т.к. если они пишут проекты типа Hello World — то да — тут не спорю. А если это распределенный проект между командой разработчиков, то руководитель проекта вас за такие вот вольности по головке не погладит. Но к 1С это все равно не относится.

    Reply
  21. protexprotex

    (21) А по поводу ошибок — там синтаксический контроль есть. Он об таких ошибках сообщит.

    Reply
  22. Dementor

    (22)

    Т.к. если они пишут проекты типа Hello World — то да — тут не спорю. А если это распределенный проект между командой разработчиков, то руководитель проекта вас за такие вот вольности по головке не погладит.

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

    Нет, у руководителя проекта никаких возражений не было. Общие *.hpp для разных проектов отлично компилировались в промежуточные *.a файлы, которые далее уже больше не пересобирались без надобности и использовались в линковке различных бинарников. Вся магия в правильно настроенных мейк-файлах.

    Да, к 1С не относится и слава Богу 🙂

    Reply
  23. Dementor

    (23) Есть такой. Помню как-то запустил синтаксический контроль по типовой торговле — насыпалась куча ошибок про отсутствие назначенных обработчиков и прочая мелочь. А ведь это писала «элита 1С» 🙂 Рассматривайте визуальную часть формы как заголовочный файл, где в событиях прописаны названия функций и предопределен состав реквизитов. Вот как сейчас платформа позволяет делать ошибки, так и с внедрение еще одного промежуточного слоя ничего не изменится!

    Reply
  24. protexprotex

    (25) Ну, может быть. В общем, для 1С (пока) это не надо. Но именно создатель С++ очень трепетно относился к такому разделению 🙂

    Reply
  25. eugeniezheludkov

    (22) вот я понимаю зачем нужен интерфейс в ООП языках типа ява, шарп, но вот зачем нужно дублировать информацию при помощи .h не понимаю! пока разрабатываешь без ТЗ, сигнатуру метода класса перепишешь миллион раз и каждый раз нужно лезть в этот .h и переписывать его там причем не так как в cpp файле, честно — это ужасно.

    конечно тут все дело в волшебных ИДЕ которые должны сами лезть и исправлять все в .h , но например ArduinoIDE, vi , nano к таким не относится (((

    Reply
  26. protexprotex

    (27) h — файлы нужны для линкования ваших разработок со сторонними проектами. Делаете include «My.h» и все. И это определение делаете во всех модулях в которых используется функции из My.cpp. И линковщик соберет все. А если без h — файла, то cpp — файл Вы не сможете объявить во всех модулях. Так устроено.

    Reply
  27. Darklight

    (2)Это большая подстава. Во-первых это очень неудобно — об этом нужно помнить и, в общем-то, проектировать сам код обработчиков тоже нужн особым образом — усложняя его — вынося обработчик изменения в ещё одну процедуру.

    А во вторых — допустим форма была в другу функцию, не расположенную в модуле формы — и реквизит изменился там — то тот алгоритм, во-первых, ничего не знает об обработчиках этого реквизита в форме, во-вторых, даже если бы знал, с вероятностью близко к 100% не сможет сам вызвать этот обработчик — т.к. в 1С все процедуры в модулях по умолчанию не экспортные (private) и не могу быть вызваны из другого модуля, а программисты редко заботятся о том, как их алгоритм может использоваться другими алгоритмами вне модуля, где он написан. Даже алгоритмы в типовом коде об этом не думают — поэтому часто при переопределении алгоритма одной типовой процедуры — приходится либо выносить в отдельные модули копии ряда связанных, не изменяемых, но не экспортных типовых процедур, либо изменять их внутри типового кода — делая их экспортными.

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

    Ну и все элементы модулей алгоритмов надо делать по умолчанию экспортными (public) — чтобы скрытыми их делал программист только тога — когда оно действительно должно быть скрыто!

    Reply
  28. Darklight

    (17)Ой, не надо нам в XX век, пожалуйста. В XXI веке для этого есть ООП, свойства, интерфейсы (объектов) и паттерны MVP и MVVM (на худой конец MVC или даже «MVPVM») для отделения визуального представления от реализации.

    Reply
  29. protexprotex

    (30) Все новое — хорошо забытое старое 🙂

    Reply
  30. Darklight

    (31)Не всё; ну, или, порой, оно уж настолько старое, что уже из ряда «никто не помнит — никогда не было»

    Reply
  31. protexprotex

    (32) Ну это Вы слишком. Например, с++ builder 6 — хоть и был выпущен в 2005 году, но все же в 21-ом веке. Это примеру. Ну а C++ Builder 10.1 — я Вам по секрету скажу — вообще недавно. И там и там есть и такой порядок написания кода. Или тоже никто не помнит этого, хотя полно народу на этих системах пишет? 🙂 Ну и майкрософт — тоже в их системах программирования есть и h и cpp файлы. Или Вы другого мнения? — их там нет?

    Reply
  32. Darklight
    Reply
  33. alex_sh2008

    (34)

    А заголовочные файлы…. да кому они сейчас нужны!

    Тем кто работает на кодом в 10млн строк

    Reply
  34. Darklight

    (35)Надо полагать Вы имели в виду 10мл строк только заголовочных файлов 😀

    Кстати, забыл добавить, что, скажем, C# имеет возможность оформлять частичные классы (с частичными методами) — где описание и реализацию одного класса можно разделить на разные файлы, причём подчёркиваю, не только отделить реализацию метода от их определения в классе — но и само определение класса разбить на разные файлы. Это как раз сделано для тех Гениев, что не настолько талантливы, чтобы редуцировать свои идеи до более компактных абстракций, что комплексно собирались бы из разных классов, но уже настолько сумасшедшие, чтобы мыслить единой логикой API в 10млн строк.

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

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

    Reply
  35. protexprotex

    (34) Вам уже ответил Александр alex_2h2008. Мне добавить нечего.

    Reply
  36. protexprotex

    (36) Вообще — то h — файлы не для сворачивания кода используются, а для подключения внешних библиотек к своему коду. У 1С такая парадигма — давайте все что нужно/не нужно соберем в среду разработки -> и получается, что инсталлятор самой 1С-ки получается такой, что в пору терабайтники уже скоро покупать, и памяти надо гигов 8 и т.д. А вот в (например) в C++ builder — там другая парадигма — например, надо Вам работать с http — подключите head (h) файл соответствующего компонента — и работайте с ним. А если Вам не нужен компонент indy — то и не подключайте его. И память не занимает и др. Но тут 1С-кам деваться некуда — у них язык — интерпретатор. Их код 1С выполняется на стековой машине — без самой 1С — он и не запуститься. Это не exe-файл.

    Reply
  37. Kosstikk
    Reply
  38. Darklight

    (38)Тогда это больше походит на холивор что лучше Java или Assembler(C++) или что лучше — Платформа высокого уровня абстракции доступа к данным, или — куча библиотек начиная от низкоуровневого доступа к памяти и диску, заканчивая алгоритмами визуализации и обработки коллекций….

    Reply
  39. Darklight

    (39)Знаем мы вас: сначала захотите наследование, затем полиморфизм, а там уже, вам, и множественное наследование подавай….

    Reply
  40. protexprotex

    (40)

    Assembler — классная штука! — Это просто лебединая песня программирования. Писать на нем — одно удовольствие. В некоторых школах программирования даже учат только на ассемблере. Ну а так — к каждой области — свой язык программирования. На 1С никто не будет писать текстовый редактор. Для этого 1С не предназначена. На Assembler никто не будет писать интерфейс к базе данных. Для этого есть 1С, c++ builder, delhi и пр. А по поводу h- файлов — так это было просто теоретическое предложение. Не концентрируйтесь на этом уж больно сильно.

    Reply
  41. alex_sh2008

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

    Reply
  42. Darklight

    (43)Разные методы декларирования API (в т.ч. описанные мной выше) и конкретная реализация, пришедшая, по большей части ещё с процедурного программирования, в виде отдельного заголовочного файла — это вещи разных плоскостей, разного уровня. В исходном комментарии автор насаждал идею, что выделение определения API в отдельный заголовочный файл — это хорошо и надо в возвращаться к корням. На что я возразил — что сейчас, в XXI веке, для достижения цели формирования API используются уже совсем иные методики. Далее разговор стал скатываться в области технологий взаимодействия разных библиотек и разных приложений друг с другом; и в проблемы оформления гигантских классов, где я пояснял как сейчас идёт развитие идей программирования в других языках, без какой-либо возврата в каменный век. Да, платформа 1С и IDE (включая EDT) почти ничего из этого не умеет, а жаль… но будем надеяться — когда-нибудь и платформа 1С будет иметь высокоразвитую и современную среду разработки, позволяющую поддерживать большое приложение.

    Кстати, с приходом в императивный стиль программирования идей из функциональных языков — в императивных языках появились анонимные функции и лямбда-выражения — они вообще не имеют декларации в полном смысле этого слова — только, в лучшем случае, список входных/выходных параметров — да тело алгоритма. А используемые переменные вообще могут захватываться из вызывающего их кода. Такие функции вообще не определяются нигде, кроме места их передачи в другой алгоритм. Или же код инициализации/получения/установки значения свойств объектов может быть написан по месту определения этих свойств, без декларирования отдельных функций, и даже без указания типа этих свойств — он будет выведен из выражения геттера или инициализатора. Собственно, наверное это и побудило отказаться от пережитков прошлого — отдельных заголовочных файлов — уж больно много стало скрытой кодогенерации, на основе выражений и программного кода, который стал размещаться сразу по месту определения структуры или месту применения.

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

    А модели пострения форм MVVM — алгоритмы могут размещаться прямо в элементах формы (как это было в 1С 7.7).

    Но это всё так…. мелочи…

    Reply
  43. alex_sh2008

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

    Reply
  44. karimov_m

    (28) Мягко говоря это не так)

    h или hpp файлы нужны в первую очередь для удобства программистов.

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

    Это становиться более очевидным, когда речь идет именно о С++ где есть парадигма шаблонов и шаблонных-классов.

    В С — .h и .с файлы просто разделяли логику описательную и саму реализацию. В контексте линковщика — в целом, без разницы в каких фалах все находиться (хоть в .hppst расширение закинь) — он просто имеет понимание что необходимо протрассить вначале (определения и типы) чтобы в дальнейшем исполняемых код имел все данные для корректного компилирования.

    Reply
  45. karimov_m

    (33) Это просто дань языку, в частности С++. В паскале есть модули (что фактически тоже самое) можно подключить его так: $I file.inc

    Reply
  46. karimov_m

    (34) кому нужны? Расскажите это программистам которые пишут код для спутников, телекоммуникационного оборудования, военной и аэрокосмической отрасли. Там все так же рулят процедурное (прямое) программирование + функциональное. Реализация алгоритмов на ПЛИС, создание алгоритмов Цифровой обработки сигналов и т.д. итп..

    Reply
  47. karimov_m

    (38) Это тоже частный случай (подключение внешних библиотек)

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

    Reply
  48. karimov_m

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

    Тут дело в чем. Реализация всего этого — основывается в конечном счете на реляционную модель БД, которая в бэке 1С.

    Тем не менее — искусственными подходами можно добиться и реализацию Классов и наследование и (боже мой) Полиморфизм. Это лишь вопрос: кто на что готов заморочится. Пока система не подразумевает такого подхода (платформоориентированного ООП) в своем продукте — надо использовать то что имеешь)

    Reply
  49. karimov_m

    (41)Да да! и побольше! И перегрузку операторов нативную хотим и передачу кода как параметра функции (лямбда) =)

    Reply
  50. protexprotex

    (46) Тут написано в контексте основного отличия применения h-файлов от применения функции Далее (как в 1С 7.7)

    Reply
  51. Darklight
    Reply
  52. karimov_m

    (53) много текста) Суть — если очень захотеть, можно к Марсу полететь. Конечно все это можно сделать. Но вот уровень ошибок (как логических там и платформенных) — будет много больше. Это немного другой уровень программирования, грубо говоря, для «Бизнес-программирования» — это излишне (в большинстве случаев).

    Второй момент — это все же концепция ORM (Объектно-реляционное отображение»), которая является суть 1С только без ООП — «технология программирования, которая связывает базы данных с концепциями объектно-ориентированных языков программирования». 1С идет дальше предоставляя помимо подхода ORM, еще интерфейсные реализации, аналитические подходы, накопительные, расчетные и прочие элементы и подходы в проектировании систем. Думаю, для бизнес приложений — это более чем достаточно, а все остальные сложные участки (ГИС, Мультимедиа, сложная Криптография и тп.) должны реализовываться и подключаться как сторонние библиотеки, для обеспечения нужд и вызовов из БизнесПлатформы, что 1С делает на текущий момент вполне продуктивно.

    Reply
  53. karimov_m

    По мне, так интересным новым расширением языка или механизмов платформы — было бы более мощный и производительный аналитический и статистический аппарат. Чтобы можно было оперировать данными так же, как например в языке R. Это было бы более выгодное направление в развитии платформы, чем внедрение ООП

    Reply
  54. Darklight
    Reply
  55. karimov_m

    (56)Как вы говорите — концепция ООП есть в 1С, да, но только в базовом случае. Есть только «подход» изначально взятый из объектного мира (но не из ООП программирования!) — что есть Класс объекта (Документы, Справочники и тп.) и их отдельный сущности (Докуемнт. Справочник и тп.). Вот и вся ООП в 1С.

    — Определение источников данных:

    ну т.е. реализовать DDL инструкции языка SQL.. опять же, это повышает порог входа и изучения. Необходимо помнить — о многопользовательской архитектуре системы и множества связей объектов между собой. Трудно представить такую необходимость.. в конечном счете это будет ТаблицаЗначений. Если надо временное создание источника данных — есть временный таблицы для решения локальных задач вычисления. Конструировать в рантайме сколько нибудь долгих по времени использования источников данных (таблиц и тп.) — можно в режиме проектирования системы. Реализовать изменяющиеся во времени составы данных (типа расширение состава ТЧ) — решаются созданием связкой и отношением нескольких таблиц (регистров) и одного справочника.

    — Маркеры сущностей и — Требования данных

    это какая-то специфика реализации.. но не направление развития..

    Сейчас тренд идет на машинное обучение и, в частности, умных индексов, которые сами себя создают, основываясь на анализе запросов, их частоты и существующих данных, выбираемых этими запросами. И все это динамически — какие запросы Нынче и какие данные — такие и индексы ML строит на них и модифицирует их.

    Плюс анализ самых частых обращений к модулям, самых сложных по весу операций переброски Сервер-Клиент и т.п. На основании этого выделять обработку таких вызовов на отдельные компоненты сервера предприятия — вплоть до создания «inmemory DB» и кэширования таких сложных запросов/вызовов ней, после чего все что накопилось потихоньку мэппить в SQL и раскладывать по табличкам. При этом надо учитывать параллельные транзакции к тем же данным.

    Вот это было бы круто.. и реальный прирост скорости. Конечно никто не отменяет умение строит архитектуру системы..

    Reply
  56. Darklight

    (57)Дело не только в приросте скорости. Дело в повышении уровня абстракции, через повышение декларатативного стиля программирования (и использования). То есть должно быть больше таких понятий как «у меня есть», «тут есть связь», «я хочу», «посчитай», «преобразуй к виду», «совмести». Которые уже транслируются к оптимальному набору машинных операций и выборок данных, без повторений. Именно повышения уровня декларатативности ведёт к повышению возможностей машины самой решать как ей лучше делать и как ей это всё делать параллельно и без блокировок!

    Reply
  57. karimov_m

    (58) ну это в иделе. Суть такого подхода будет стремиться к следующему выражению: «1с, а 1с — а сделай выборку всех незаблокированных договоров (справочник) контрагента ООО Ромашка и верни таблицу взаиморасчетов по дебиторке в разрезе этих договоров, только той дебиторке, что критически просроченная, которая образовалось более 80 дней назад. Описание возвращаемых полей данных возьми в справочнике «состав полей отчета ДЗ» »

    Этак так и программисты скоро не нежны будут)

    Reply
  58. Darklight

    (59)просто в очередной раз изменится парадигма программирования. Как когда-то она изменилась от машинных кодов простых операций над числами к ассемблеру далее к императивному стилю — далее к функциональному или логическому стилю, далее ответвление на программирование на нейросетях, далее к метопрограммированию, затем к полному декларатативному стилю (что там будет с парадигмами программирования далекого будущего пока судит сложно — но, будет ещё не один качественный переход, покрайней мере, следующая парадигма будет основана на нечёткой логике, вероятностях значений, предсказаниях событий и непрерывных параллельных ветвящихся вычислениях с неполными известными). И спрос на программистов будет только повышаться пока они не разработают ИИ, который будет себя совершенствовать быстрее и лучше, любого человека… и настанет эпоха сингулярности развития науки и общеста!

    Reply
  59. karimov_m

    (60) ИИ уже делает другие ИИ лучше, чем человек )

    Reply
  60. starik-2005

    Интересное обсуждение, только вот не совсем понятно, зачем ООП мешать с объектами, хранимыми в БД? Ну пусть они там хранятся как набор определяемых в конфигураторе данных, а вот обработка этого набора — вот это и есть хранимые отдельно методы объектов. Данные — отдельно (в БД), методы — отдельно (в конфигурации БД). Зачем наследовать документ? Достаточно наследовать его программную реализацию, т.е. код. При необходимости создавать объект, наследующий программный интерфейс от другого объекта, часть методов которого нужно переопределить (например, заказ поставщику, поступление, заказ покупателя, реализация, … — товарные документы, в которых общего кода достаточно). С другой стороны, все это реализуется через общие модули, экспортные процедуры которых могут быть переопределены в другом модуле — достаточно вызвать вместо метода «ЗаказПокупателя.МояПроцедура» метод «Реализация.МояПроцедура». Для реализации подобного поведения ничего не нужно толком, ибо вызывая «МойОбъект.МояПроцедура» можно автоматически получить тот самый полиморфизм, когда объект вызывает тот метод, который ему предназначен (т.е. фактически если есть стопиццот разных объектов с этим методом, то каждый из них вызовет тот метод, которые для него определен в его модуле).

    Т.е. ООП в плане работы с прикладными объектами 1С не особо нужен — все в нем уже есть. А вот реализация самих объектов, отделенных от данных, также передаваемых в качестве аргументов функций (типа «СделатьЧтоТо(@ФункцияДеланияЧегоТо)») и прочие интересные конструкции — вот это было бы к месту.

    Reply
  61. karimov_m

    (62) Всё так, согласен.

    Но наследовать можно (и нужно иногда) не только программный код класса (документа) но и его данные (реквизиты).

    Фактически, если мы наследуем только код, то мы объявляем интерфейс и его возможные реализации.

    Reply
  62. starik-2005

    (63)

    но и его данные (реквизиты)

    Фактически при таком наследовании либо создается новая таблица в БД для новых данных (или Вы думаете, что для разных экземпляров объектов, унаследованных от базового, можно иметь разное количество колонок в реляционной базе? Это не так — тогда уж нужно использовать объектные базы, и получите все эти веселые штуки с типом экземпляра, версией, самим объектом, который внезапно оказался немного не тем, а код снова унаследовался — тут достаточно копирования объекта в конфигураторе и добавлении к скопированному нужных колонок, или просто регистр по типу допреквизитов с характеристиками в запросе, которые и так работают, а если сильно что-то надо — есть расширения, которые колонки могут к объекту добавить — но там и проблем с этим масса).

    Смысл наследовать что-то, кроме кода, я, например, не вижу. По крайней мере в реляционной модели данных.

    Reply
  63. karimov_m

    (64) Вот, и тут мы подходим к тому, что вы писали выше

    зачем ООП мешать с объектами, хранимыми в БД?

    ))

    Суть не в наследовании «данных» как таковых. А в наследовании их структуры, а во множественном наследовании — это суть строительство нужных классов/объектов (документов) из базы.

    — Вот тут у нас класс с данными по «базовым данным» (дата. время ввода, код, еще какой-то признак (пометка))

    — Вот тут у нас класс с функционалом открытия формы (причем любой формы), ее позиционирования и других действий

    — Вот тут есть класс (неплохой такой) — он внедряет возможность иметь объекту Табличную часть!

    — Воу! Продолжим наследовать/миксовать — вот класс такой: писать в таблицу/регистр и методы/код — и вот наш Новый Класс — почти что документ, который может делать проводки, иметь ТЧ. От него я буду создавать все остальные документы.

    А если мне понадобиться расширить функционал Класса ТабличаняЧасть ? Например методом «Свернуть» ? Отлично — просто добавим реализацию в него, и все документы получат его в наследство, а еще и добавим новый реквизит — «уникальный идентификатор строки ТЧ» — это уже описательная часть Класса ТабличначЧасть.

    Примерно в таком направлении можно думать об ООП. Но в 1С нет ООП, в нем можно программировать подходами ООП

    Reply
  64. starik-2005

    (65)

    А если мне понадобиться расширить функционал Класса ТабличаняЧасть ? Например методом «Свернуть» ?

    А где тут привязка к БД? Табличная часть — это объект со своими методами, набор колонок — это лишь коллекция, которая просто для разных данных будет содержать разные значения. Наследовать содержимое этой коллекции бессмысленно.

    Reply
  65. karimov_m

    (66) Еще раз. Наследование кода — это одно. Наследование данных как описание их структуры — это совсем другое. Посмотрите — есть «базовая структура» ТЧ — состоящая из колонок (шапка таблицы — это и есть описание структуры) и потенциальных строк (в каждом конкретном экземпляре объекта). Например «Номер строки» — это колонка, суть описание структуры данных ТЧ, он то и наследуется. А какие там потенциальные «значения», которые будут храниться в памяти, описано этой структурой — это уже будет известно при выделении конкретного объекта и его жизни.

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

    Reply
  66. starik-2005

    (67)

    Наследование данных как описание их структуры — это совсем другое.

    А примеры будут?

    Reply
  67. karimov_m

    (68) примеры чего?) Повествовательная часть моего высказывания уже пример)

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

    Я не сторонник отстаивания мнения ради самого процесса отстаивания..

    Reply
  68. Darklight

    (61)Формально да, но формально сейчас ещё нет полноценного ИИ — лишь его математические имитации.

    Reply
  69. karimov_m

    (71) ну это уже общее определение.

    Тут вопрос, что в вашем понимании «полноценное ИИ»..

    Отсылки к созданию ИИ общего назначения? Это в проектах, но и это будет. Квантовые вычисления этому поспособствуют..

    Reply
  70. Darklight
    Reply
  71. Darklight

    (72)Думаю, полноценный ИИ это сознание, которое определяется через самосознание себя как живого/мыслящего существа/индивида (т.е. разум, не способный определить себя как искусственный); и через призму восприятия других существ/индивидов — которые не смогли бы в общении определить этот разум как искусственный. Ну, и добавлю, плюс способный создать новый разум, который аналогично воспринимал бы себя (причём, создатель по-прежнему не смог бы сам себя посчитать искусственным разумом, даже после того, как сам же создал новый искусственный разум, обладающий тем ми же качествами, т.е. в т.ч., не способный самостоятельно определить, что он искусственный, и способный далее создавать такой же). Сложно выразился, прошу прощение… наверное просто не в духе сейчас давать изысканные определения.

    Reply
  72. karimov_m

    (73)эм.. это Нургалиеву короче)) (и копию письма Бьёрну Страуструпу)

    Reply
  73. starik-2005

    (70)

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

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

    Т.е. вот, допустим, есть у нас некий объект БД, который мы, допустим, определили програмно как-то так:

    ТЧ = Новый ТабличнаяЧасть;
    ТЧ,Колонки.Добавить(«Колонка1», Новый ОписаниеТипов(«Строка»));
    

    Т.е. тут мы описали какую-то табличную часть, которую можем использовать в каком-то объекте. Допустим, как-то так:

    Док = Новый Документ;
    Док.ТабличныеЧасти.Добавить(ТЧ);
    

    Дальше мы можем, допустим, унаследовать данные от этого объекта и развить что-то, да? Ну, например, так:

    Док1 = Новый Документ(Док);
    Док1.ТабличныеЧасти.Добавить(ТЧ1);

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

    Если говорить об ООП, то придется написать все иначе. Т.е. как-то так:

    Объект Документ1 От Документ
    НачалоОписанияОбъекта
    Перем ТабличныеЧастиДополнительные; // как бы указать, что это коллекция табличных частей…
    Перем НомерВходящегоДокумента; // как бы указать, что это строка
    Записать(РежимЗаписиДокумента Режим); // тут мы переопределяем метод «Записать()».
    
    КонецОписанияОбъекта;
    
    Процедура Документ1 .Записать()
    // что-то как-то иначе записываем…
    КонецПроцедуры
    

    Показать

    Но фактически это уже и так реализуется с помощью конфигуратора, и у нас нет проблем с описанием унаследованного от базового документа какого-либо «акта приемки-передачи» — все на этапе конфигурирования в виде конструктора доступно, а методы — пожалуйста, хоть статику в модуле менеджера плоди, хоть динамику в модуле объекта фигач…

    Т.е. хотелось бы конкретного примера с обоснованием, зачем это нужно.

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

    Reply
  74. karimov_m
    Reply
  75. webester

    (59)

    Этак так и программисты скоро не нежны будут)

    Я бы не сказал, что и сегодня они особо нежны

    Reply
  76. monkbest

    (1) и правильно, иначе попадете в рекурсию в 99% случаев обработки события

    Reply
  77. user922183

    Спасибо. Помогло

    Reply

Leave a Comment

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