Команды формирования объектов. Команды конструирования объектов Основные команды и операции

Три или более объекта, затем:

    выполните команду «Формат > Выровнять/Распределить > <вариант действия>» главного меню;

    выполните команду «Выровнять/Распределить > <вариант действия>» контекстного меню;

    на панели инструментов «Выравнивание » нажмите кнопку, соответствующую необходимому действию.

Доступны следующие варианты выравнивания/распределения объектов:

    Выровнять по левому краю . Выделенные объекты будут выровнены по левому краю относительно крайнего левого объекта:

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

    Выровнять по правому краю . Выделенные объекты будут выровнены по правому краю относительно крайнего правого объекта:

    Выровнять по верхнему краю . Выделенные объекты будут выровнены по верхнему краю относительно крайнего верхнего объекта:

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

    Выровнять по нижнему краю . Выделенные объекты будут выровнены по нижнему краю относительно крайнего нижнего объекта:

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

    Распределить по вертикали . Выделенные объекты будут находиться друг от друга на одинаковом расстоянии. Расстояние рассчитывается аналогично предыдущему пункту:

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

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

В команду можно передать параметры, например, из формы какого объекта он вызывается.

Настройка и свойства общей команды в 1С

Добавить новую команду и настроить общую форму достаточно просто, рассмотрим этот процесс подробнее:

Получите 267 видеоуроков по 1С бесплатно:

  • Группа — расположение будущей команды на интерфейсе.
  • Тип параметра команды — определяет набор объектов, в котором будет отображаться будущая команда.
  • Режим использования параметра — задает возможность передать в качестве параметра команды одно или несколько значений.
  • Изменяет данные — если галка установлена, то при выполнение команды форма будет пересчитана с сервера.
  • Модуль команды — обработчик выполнения команды, выполняется на клиенте.

Пример модуля команды:

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

Здесь ПараметрКоманды — объект, вызывающий команду. А в ПараметрыВыполненияКоманды структура, в которой описан Источник (вызываемая Форма), Окно (ОкноКлиентскогоПриложения), Уникальность, указывает, искать ли уже открытую форму или нет.

Группы команд 1С

Большая часть современного ПО разрабатывается группами программистов. Кто-то отвечает за пользовательский интерфейс, кто-то за ядро, а кто-то за дополнительные модули. Чтобы работа всех этих людей не пропала даром, нужно грамотно объединить разные части проекта, не забыв при этом о возможном его расширении. Для этого нам пригодится паттерн проектирования «Команда», который инкапсулирует в себе исполнителя задачи и ее условия.

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

Казалось бы, всё просто: накодил большой блок switch, который при нажатии разных сочетаний кнопок вызывает ту или иную функцию какого-либо модуля, и радуйся. Но, во-первых, такой подход не отличается гибкостью. Когда проект пополнится новыми модулями или hotkeys, нам придется менять код этого раздутого оператора ветвления, из-за чего он впоследствии раздуется еще больше. А во-вторых, начальство большими красными буквами написало, что у пользователя должна быть возможность переназначить эти горячие клавиши. Таким образом, жестко забить команды в код switch у нас точно не выйдет.

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

Интерфейсы модулей, доступные для обращения через HotKeys class Calculator { public: void runCalc(); void closeCalc(); } class Printer { public: void printDocument(); void printImage(); void printEmail(); } class Browser { public: void runBrowser(); void closeBrowser(); } // И дальше много всяких разных классов

Паттерн «Команда»

Отбросив лирику, перейдем к изучению паттерна «Команда», который должен помочь нам в этом нелегком деле. Для начала следует разобраться, что мы имеем. У нас есть множество модулей с самыми разнообразными API. Также у нас есть окошко, в котором пользователь может выбрать из списка одну из команд, предоставляемых модулями, и закрепить ее за определенным сочетанием клавиш.

Формально выражаясь, обработчик нажатий клавиатуры - это клиент, API-функции модулей, вызываемые с помощью горячих клавиш, - это задачи, а модули, предоставляющие эти задачи, - это исполнители. Окошко с настройками hotkeys представляет собой некий посредник между клиентом и исполнителем, скрывающий все детали выполняемых операций. Такая структура позволяет полностью отделить клиент от исполнителя, то есть пользователь понятия не имеет, какой модуль работает при нажатии той или иной комбинации клавиш и что он делает. И это очень хорошо, так как чем лучше изолированы друг от друга части кода, тем надежней работает программа.

Для такой изоляции нам нужно определить объект команды, а следовательно, и соответствующий интерфейс. Он достаточно прост и определяет всего один метод execute(), который должен выполнять метод какого-либо из модулей.

Интерфейс объекта «Команды» class Command { public: void execute() = 0; }

Для определения конкретного объекта мы просто объявляем новый класс, который наследует интерфейс Command, и определяем его метод execute(). Допустим, мы хотим создать команду, запускающую калькулятор. Для этого мы создадим класс RunCalcCommand, который будет наследовать интерфейс Command, и переопределим execute() для вызова метода runCalc() модуля Calculator.

Команда запуска калькулятора class RunCalcCommand: public Command { Calculator *calc; public: RunCalcCommand(Calculator *excalc) { calc = excalc; } void execute() { calc->runCalc(); } }

Если внимательно присмотреться к коду команды, то можно заметить, что в конструкторе класса RunCalcCommand передается указатель на модуль Calculator. Это сделано для большей гибкости. В будущем у нас может появиться класс ModernCalculator, вызывающий продвинутую версию расчетной программы. Используя композицию, то есть не фиксируя исполнителя жестко в коде, мы увеличиваем изолированность кода, что в будущем позволит сэкономить время.

Теперь нужно связать команду с хоткеем. Для этого можно создать массив указателей на объекты класса Command. Размер массива будет равен количеству поддерживаемых горячих клавиш. Каждый элемент массива команд сопоставляется с определенным хоткеем. В нашем случае для этого можно преобразовать значение кнопки, которая вместе с Ctrl составляет какое-либо из возможных сочетаний, в числовое значение. Если бы мы использовали сочетания, например, от ctrl-a до ctrl-k, то нам бы потребовался немного другой подход.

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

Назначение команды на hotkey и ее запуск // Код инициализации команды и хоткея const int comCount = 10; Command* commands; Calculator *calc = new Calculator(); commands = new RunCalcCommand(calc); // Код в обработчике нажатий клавиатуры // Получаем нажатые клавиши hotkey = catchHotKey(); // Преобразовываем их в индекс и запускаем команду int index = hotkey2index(hotkey); commands->execute();

Всё довольно-таки просто. Можно определить еще несколько наследников Command, которые будут выполнять определенные действия, и связать их с горячими клавишами. Такая архитектура позволяет полностью отделить клиент от исполнителей. Обработчик клавиатуры понятия не имеет, какой модуль обрабатывает команду и что именно он делает, а модули, в свою очередь, не подозревают, что обращение к ним осуществляется с помощью hotkeys, а не каким-то другим способом.

Отмена команды

Вроде бы всё хорошо, но мы совсем забыли про отмену. Сочетание клавиш ctrl-z должно откатывать действие последней команды. Реализовать отмену довольно просто, хотя на первый взгляд может показаться, что это совсем не так. Для этого мы немного изменим интерфейс Command.

Класс Command, поддерживающий отмену class Command { public: void execute() = 0; void undo() = 0; } class RunCalcCommand: public Command { Calculator *calc; public: RunCalcCommand(Calculator *excalc) { calc = excalc; } void execute() { calc->runCalc(); } void undo() { calc->closeCalc(); } }

Мы просто добавили метод undo(), который должен быть переопределен в классах-наследниках. Программист сам решает, какую именно функцию модуля будет использовать метод отмены. Так, метод undo() для RunCalcCommand будет обращаться к функции closeCalc() модуля Calculator. Нам также потребуется немного подправить код обработчика клавиатуры.


Wikipedia про паттерн «Команда». Обработчик клавиатуры с поддержкой отмены // Код инициализации команды и хоткея const int comCount = 10; Command* commands; Command *lastCommand = new NoCommand(); Calculator *calc = new Calculator(); commands = new RunCalcCommand(calc); // Код в обработчике нажатий клавиатуры // Получаем нажатые клавиши HotKey *hotkey = catchHotKey(); // Если это отмена, то вызываем соответствующий метод if (hotkey->str() == "ctrl-z") { lastCommand->undo(); } // Обработка остальных сочетаний

Здесь мы просто запоминаем в переменной lastCommand указатель на последнюю использованную команду и при нажатии ctrl-z вызываем соответствующий метод. Дополнительно мы прибегаем к небольшому трюку, используя объект пустой команды NoCommand. Код этого класса выглядит так:

Пустая команда NoCommand class NoCommand: public Command { public: void execute() {}; void undo() {}; }

Такие объекты-заглушки используются довольно часто. Они нужны, чтобы уменьшить количество проверок нулевого указателя. Если бы lastCommand был равен NULL, то перед вызовом метода undo() нам пришлось бы проверять корректность значения этого указателя, что нежелательно, так как однажды мы можем забыть это сделать, в результате чего программа с грохотом упадет. Такие же объекты-заглушки рекомендуется использовать и для остальных хоткеев, которым не назначены соответствующие команды.

Кстати, код обработчика клавиатуры можно модифицировать так, чтобы он поддерживал отмену не только последней операции, но и вообще всех цепочек выполненных команд. Для этого вместо простого указателя на последнюю команду следует использовать стек. При обработке какого-либо хоткея в стек будет добавляться указатель на соответствующую команду. Таким образом, мы получим полную историю вызовов команд, что позволит нам последовательно все отменить при помощи ctrl-z.


Макрокоманды

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

Макрокоманда class MacroCommand: public Command { Command *commands; int comCount; public: MacroCommand(Command *comArray, int elemCount) { commands = comArray; comCount = elemCount; } void execute() { for (int i = 0; i < comCount; i++) { commands[i]->execute(); } } void undo() { for (int i = 0; i < comCount; i++) { commands[i]->undo(); } } }

Как видно, класс MacroCommand является наследником Command и переопределяет всё те же методы execute и undo. В интерфейсе от обычной команды он отличается лишь конструктором. Этот класс принимает не указатель на исполняющий модуль, а массив указателей на простые команды. Код execute() просто проходит по элементам массива и вызывает каждый из них. Так же ведет себя и undo(). Обработчик клавиатуры при обращении к объекту команды понятия не имеет, макрос это или обычная единичная операция, - главное, что все они предоставляют функции execute() и undo().

Расширенные возможности паттерна «Команда»

Наш паттерн можно использовать не только для обработки горячих сочетаний клавиш. С помощью него можно организовывать очереди запросов. Допустим, что у нас есть пул потоков, который должен выполнять некоторые задания. Все задания представляют собой объекты, реализующие уже знакомый нам интерфейс Command. Команды выстраиваются в очередь, к которой последовательно обращаются потоки. Они забирают команды из этой очереди и запускают их методы execute(). Потокам не важно, что делают эти объекты - главное, чтобы они поддерживали вызов execute(). Команды можно сохранять на жестком диске и восстанавливать их оттуда. Для этого следует немного расширить их базовый интерфейс.

Command с поддержкой сохранения и загрузки class Command { public: void execute() = 0; void undo() = 0; void load() = 0; void store() = 0; }

Метод load() предназначен для сохранения команды в журнале, а store() - для ее восстановления оттуда. Код этих методов может использовать механизмы сериализации языка программирования, если таковые в нем есть. Такая функциональность нужна для работы с большими объемами данных, которые невозможно сохранять после совершения с ними каждого действия. При сбое программы мы сможем загрузить сохраненные команды и последовательно применить их к имеющейся копии данных для приведения этих данных в актуальное состояние.

Заключение

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

Технологическая платформа «1С:Предприятие 8» используется для автоматизации решения широкого круга управленческих и учетных задач на самых разных предприятиях. При такой обширной сфере применения, естественно, могут возникать ситуации, когда функциональности стандартных команд недостаточно.
Для реализации дополнительной функциональности используется встроенный язык «1С:Предприятия». В основном эта функциональность реализована в обработчиках событий. Однако возникает и необходимость предоставить пользователям возможность интерактивного обращения к части реализованных функций из интерфейса.


Для решения этих задач в «1С:Предприятии» существует возможность создавать произвольную команду. В конфигурации произвольные команды представлены новым объектом конфигурации Команда . Объект конфигурации Команда предназначен для реализации в прикладном решении нестандартных функций с возможностью использования стандартных механизмов включения реализованного функционала
в командный интерфейс.
Технологическая платформа ничем не ограничивает состав произвольных команд и реализуемые ими функции. Все определяется требованиями к конкретному прикладному решению. При создании произвольной команды разработчик должен установить ее свойства, определяющие правила включения команды в интерфейс, и написать программный код, определяющий выполняемые командой действия. Этим произвольные команды отличаются от стандартных. Для последних и свойства, и выполняемые действия определены самой платформой.
В конфигурации произвольные команды могут быть реализованы или как независимые объекты – общие команды, или как подчиненные другим объектам.

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

Произвольные общие команды

Для примера рассмотрим, как сделать и настроить все свойства команду “Настроить сканер штрих-кодов” . На торговых предприятиях часто требуется автоматизировать процесс регистрации продаваемого товара. Для этого используются сканеры штрих-кода. Однако технологическая платформа ничего «не знает» об этих устройствах и не имеет средств работы с ними. Следовательно, для работы со сканером штрих-кода требуется подключать специальную программу – драйвер. Для подключения такого драйвера реализована общая произвольная команда Установить сканер штрих-кодов. Установив определенные значения свойств этой команды, разработчик обеспечил ее доступность пользователям.

Произвольная общая команда «Настроить сканер»

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

Еще одной распространенной задачей является получение печатных копий электронных документов. Состав документов, их структура определяются автоматизируемой прикладной задачей. Естественно, в платформе невозможно предусмотреть все многообразие документов и варианты их печатных форм. Для того чтобы «научить» документ «переносить» себя на бумагу, можно воспользоваться произвольной командой.
В демонстрационной базе для получения печатной формы документа РасходТовара создана подчиненная команда ПечатьРасходнойНакладной

Произвольная подчиненная команда «Печать расходной накладной»

Значения свойств команды Группа и Тип параметра команды определили расположение команды в командном интерфейсе – меню Печать командной панели формы документа, а процедура на встроенном языке обеспечила формирование печатной формы конкретного документа, ссылка на который передается в параметре команды.
Еще одним, достаточно специфическим вариантом использования произвольных команд является расширение или переопределение стандартной функциональности стандартной команды. Такие задачи возникают, например, вследствие требования сократить количество ручных операций или изменить стандартное поведение объектов.
Например, в нашей базе реализован объект-обработка Административный сервис . Команду открытия основной формы необходимо было расположить в панели навигации, а саму форму открывать в рабочей области основного окна приложения. Но стандартная функциональность этого объекта отличается от требуемой – команда открытия формы располагается в панели действий, а форма открывается в новом вспомогательном окне.
Для обеспечения требуемой функциональности у обработки снято свойство Использовать стандартные команды – стандартные команды нас не устраивают.

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

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

Произвольная подчиненная команда «Административный сервис»

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

Размещение по умолчанию в командном интерфейсе для произвольных команд определяется:

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

ВНИМАНИЕ!
Свойство команды Группа обязательно должно быть заполнено. В противном случае возникнет ошибка при обновлении конфигурации базы данных, и обновление не выполнится.

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

  • Если команда для своего исполнения не требует параметров, то для нее выбирают группу с категорией Панель навигации или с категорией Панели действий.
  • Если команда для своего исполнения требует передачи параметра, то для нее необходимо выбрать группу с категорией Панель навигации формы или с категорией Командная панель формы.
  • Для команд, выполнение которых приводит к изменению информации, отображаемой в рабочей области того же окна, следует выбирать категорию Панель навигации для независимых команд илиПанель навигации формы для параметризуемых команд.
  • Для команд, выполнение которых приводит к изменению данных в информационной базе, следует выбирать категорию Панель действий для независимых команд или Командная панель формы для параметризуемых команд. Также эту категорию рекомендуется выбирать для команд, которые приведут к открытию нового окна для отображения форм выбора, форм отчетов, форм обработок.

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

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

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

Сравнивая состав типов, заданных в свойстве команды, с типами реквизитов формы, система принимает решение о включении команды в ту или иную форму.

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


  • печать ценников на все товары по всем существующим видам цен,
  • печать ценников на все товары по одному виду цен.

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

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

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

Свойства и модуль общей произвольной команды

В группе свойств Основные зададим значения свойств команды:


  • Имя – «ПечатьЦенниковТовары»;
  • Синоним – оставим автоматически сформированный синоним;
  • Комментарий – заполнять не будем.

Следующий шаг – выбор категории команды и группы для ее размещения по умолчанию. Наша команда для своего исполнения не требует параметров – она независимая. Команда выполняет действия по обработке данных, хранимых в информационной базе, с целью получения набора ценников, а не изменяет контекст решения какой-либо задачи. Следовательно, для команды установим категорию Панель действий. А в какой группе она будет отображаться? Логичнее всего поместить ее в группу Сервис .
Поэтому для свойства Группа открываем окно со списком групп и выбираем элемент панель действий.Сервис .

ПРИМЕЧАНИЕ
Обратите внимание на свойства Тип параметра команды , Режим использования параметра и изменяет данные – они недоступны для заполнения. Свойства предназначены для описания параметризуемой команды и становятся доступны только при выборе группы с категориями Панель навигации формы или Командная панель формы.

Задание места размещения произвольной общей команды

Созданная нами команда является независимой. Следовательно, необходимо определить, в каких разделах командного интерфейса она будет доступна. Команда должна быть доступна в тех же разделах, в которых можно выполнять действия по управлению ценами.
В нашем случае созданная команда должна принадлежать трем подсистемам – Ценообразование, Цены, Предприятие. Таким образом, нам требуется отредактировать свойство Состав трех подсистем.
Для сокращения количества выполняемых действий из контекстного меню созданной команды выберем пункт Дополнительно. В результате откроется окно, в котором на закладке Подсистемы можно указать все подсистемы, которым принадлежит команда

Включение произвольной общей команды в подсистемы

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

Настройка доступности команды для роли «Менеджер по ценам»

Настройка видимости команды по ролям для произвольной независимой команды выполняется аналогично настройке для стандартных команд – в редакторе командного интерфейса.
Наша команда по умолчанию должна быть видима пользователю с ролью Менеджер по ценам, а от пользователя с ролью Администратор ее необходимо скрыть. Для этого в редакторе командного интерфейса подсистемы Ценообразование снимем флажок общей видимости в колонке Видимость . Это обеспечит нам невидимость команды для всех ролей, в том числе и вновь создаваемых. А для роли Менеджер по ценам явным образом установим флажок в соответствующей колонке.
Сохраним конфигурацию, запустим приложение от имени пользователя Менеджер по ценам и выберем раздел Управление ценами.

Настройка видимости произвольной общей команды

В командном интерфейсе команда Печать ценников товары доступна в разделе Управление ценами (за счет указания принадлежности к подсистеме Ценообразование). Команда размещена в группе Сервис панели действий (за счет указания соответствующего значения свойства Группа).

Таким образом, для произвольной общей независимой команды:

  • размещение в командном интерфейсе по умолчанию определяется значением свойства Группа;
  • включение в раздел командного интерфейса определяется принадлежностью к соответствующей подсистеме;
  • доступность для пользователя определяется значением права Просмотр.

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

Справочная информация по произвольной общей команде

Однако поиск описания команды в документации или встроенной справке – процесс длительный. Можно помочь пользователю быстро вспомнить назначение команды, выбрав для нее говорящее представление. Произвольная общая команда в командном интерфейсе представляется своим свойством Синоним. Сейчас команда представлена текстом «Печать ценников товары» , и это представление достаточно информативно. Но в дальнейшем мы добавим в прикладное решение еще одну команду печати ценников – по виду цен. Поэтому стоит подумать над таким представлением команды, которое подскажет пользователю, какой вариант печати ценников будет выполнен. Скажем, это будет «Печать всех ценников» .
Еще одним способом напоминания пользователю о назначении команды является использование свойства Подсказка. Текст, заданный в этом свойстве, отображается во всплывающей подсказке при наведении указателя мыши на команду. Для свойства Подсказка зададим текст «Печать ценников на все товары по всем видам цен» . В результате изменения значений свойств Синоним и Подсказка представление команды
в командном интерфейсе изменилось.

Измененное представление команды, подсказка, справка

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

ГЛАВА 4

Команды и Операции над объектами

  • Основные команды и операции
  • Выделение объектов
  • Выделение объектов с выполнением команды
  • Выделение подобъектов
  • Управление видимостью объектов
  • Клонирование объектов
  • Объединение объектов в группы
  • Трансформации объектов

2. Основные команды и операции

Основные команды и операции

Основные команды и операции над объектами в среде Мах можно определить по следующим группам:

  • Выделение объектов;
  • Выделение объектов с выполнением команды;
  • Выделение подобъектов;
  • Управление видимостью объектов; Клонирование объектов;
  • Объединение объектов в группы.
  • Трансформации объектов
  • Рассмотрим каждую из них детальнее.

3. Выделение объектов

Выделение объектов

Существует несколько дублирующих друг друга приемов для выполнения и управления операциями выделения объектов. Кроме самого традиционного из них - левого щелчка мыши на выбираемом объекте, эту процедуру можно произвести через группу пунктов Select (Выбор) из падающего меню Edit (Редактирование) (рис. 4.01).

Ниже приводится список этих пунктов с кратким описанием их функций:

  • Select All (Выбрать Все) - позволяет выделить все нескрытые и «размороженные» объекты (смысл этих терминов будет описан далее).
  • Select None (Сбросить Выделение) - снимает выделение со всех объектов сцены.
  • Select Invert (Выбрать Все Невыделенные) - выделяет инверсно все невыбранные объекты.

РИСУНОК 4.01 . Пункты выбора объектов

  • Select By Color (Выбрать По Цвету) - создать выделение по указанному цвету объекта
  • Select By Name (Выбрать По Имени) - выбрать один или несколько объектов по имени из общего списка через диалоговое окно (рис. 4.02).


РИСУНОК 4.02. Выбор объектов по имени из списка

  • Region (Область Выделения) - имеет два переключателя, задающие режим выбора объектов:
  • Window (Охват) - в набор попадают объекты, полностью помещающиеся в область выделения;
  • Crossing (Секущая Рамка) - объекты выбираются, даже если они лишь соприкасаются с областью выделения.

Также выполнение операции выбора объектов можно выполнить с помощью группы кнопок в (рис. 4.03):

РИСУНОК 4.03. Группа кнопок выбора объектов в Основной Панели Инструментов

  • Select Object (Выбрать Объект) - модальная кнопка, включающая режим выбора объектов левым щелчком мыши. По каждому левому щелчку предыдущий выбор сбрасывается и выбранным оказывается лишь один, последний из объектов. Для добавления нового объекта в набор без сброса - левый щелчок выполняется с нажатой клавишей , для исключения выбранного объекта из набора - щелчок совместно с клавишей .
  • Selection Region (Форма Области Выделения) - список кнопок для изменения формы области выделения объектов. Может быть задана как Rectangular (Прямоугольная), Circular (Круглая) или Fence (Ломаная).

Для выбора нужной формы нажмите на эту кнопку (до появления всего списка) и, удерживая левую кнопку мыши, перемещайте курсор по списку, отпустив ее на соответствующей кнопке.

Select By Name (Выбрать По Имени) - кнопка, вызывающая упоминавшееся ранее диалоговое окно Select Objects (Выберите Объекты) (рис. 4.02). Остановимся на его параметрах.

Основное информационное поле содержит список объектов сцены, причем порядок сортировки и способ показа зависит от групп настроек Sort (Сортировка) и List Types (Список Типов).

Первая из них позволяет задавать способ сортировки имен объектов сцены по Alphabetical (Алфавиту), By Type (Типу), Color (Цвету) и Size (Размеру).

Флажки группы List Types управляют правилом, какие из категорий объектов Мах будут показаны в общем списке, а какие - скрыты. Кнопки Аll (Все), None (Ничего) и Invert (Инвертировать) необходимы для быстрого управления всем набором флажков группы.

Дополнительный список флажков в левой нижней части окна управляет следующими параметрами:

  • Display Subtree (Отобразить Иерархию) - включение отображения объектов, имеющих иерархические связи или открытых групп (группы будут рассмотрены далее).
  • Select Subtree (Выделять Иерархию) - включение выбора таких объектов.
  • Case Sensitive (Регистрозависимость) - влияние регистра в наборе имени в верхнем текстовом поле.
  • Select Dependents (Выбор Зависимых Объектов) - выбор объекта вызовет одновременный выбор всех его Instances (Экземпляров) и References (Ссылок).

Кнопки АИ (Все), None (Ничего) и Invert (Инвертировать) над этим списком позволяют быстрое управление выделением имен объектов. И, наконец, список Selection Set (Именованные Наборы) позволяет осуществить выбор одного из нескольких предварительно созданных и названных наборов объектов. Далее в этой главе мы подробно остановимся на создании таких наборов.

Для выбора категории объектов, с которыми производится выделение необходимо использовать Selection Filter (Фильтр Выбора). Этот список позволяет выбрать одну или несколько категорий объектов для работы с ними и исключить остальные.

Значение списка Аll (Все Объекты) применяется ко всем объектам сцены и снимает все ограничения.

Изображение:

Изображение:

4. Выделение объектов с выполнением команды

Выделение объектов с выполнением команды

Остальные кнопки в описывемой группе в Main Toolbar (Основной Панели) все являются модальными и дают возможность, произведя выбор, перейти к выполнению соответствующей команды:

  • Select and Link (Выбрать и Связать) - выполняет операцию иерархической связи подчиненных объектов сцены по типу Parent-Child (Родитель-Потомок).
  • Select and Move (Выбрать и Переместить) - позволяет начать перемещение объекта или объектов сразу после завершения выделения.
  • Select and Rotate (Выбрать и Повернуть) - то же для операции поворота над выбранными объектами.
  • Select and Scale (Выбрать и Масштабировать) - в зависимости от текущего состояния списка кнопок Scale это может быть операция Uniform (Однородного), Non-Uniform (Неоднородного) масштабирования и Squash (Сплющивания) сразу по окончании выбора.

Для создания Named Selection Set (Именованного Набора) необходимо выполнить выделение нужных объектов и ввести уникальное имя в текстовом поле списка имен в Main Toolbar (Основной Панели) (рис. 4.04).

Каждое новое имя добавляется в список имен и сохраняется в файле проекта Мах. Для настроек и изменений именованных наборов служит диалоговое окно Named Selection Set (рис. 4.05), которое вызывается командой Named Selection Sets (Именованные Наборы) в меню Edit, или одноименной кнопкой на основной панели инструментов.


РИС. 4.04. Список Именованных Наборов


РИСУНОК 4.05. Редактирование Именованных Наборов

Кнопки, расположенные в верхней части этого окна позволяют:

  • создавать новые наборы;
  • удалять выбранный в диалоговом окне объект из набора или удалять весь набор;
  • добавлять выбранный в окне программы объект к набору;
  • удалять выбранный в окне программы объект из набора;
  • выделять в окне программы объекты, которые входят в выбранный в диалоговом окне набор;
  • выбирать объекты по их имени с помощью диалогового окна Select Objects.
  • подсвечивать выбранные в диалоговом окне объекты.

Изображение:

Изображение:

5. Выделение подобъектов

Выделение подобъектов

Возможность работать с Sub-Objects (Подобъектами) возникает в том случае, если выбранный объект имеет многоуровневую структуру. Подобъектами в среде Мах являются уровни Vertex (Вершина), Segment (Сегмент) и Spline (Кривая) в объектах типа Shape (Форма); Vertex (Вершина), Edge (Ребро), Face (Грань), Polygon (Плоскость) и Element (Элемент) в объектах типа Mesh (Каркас) и т.д. Любой из модификаторов - особых инструментов изменения внутренней структуры объектов - может иметь уровень Sub-Object (Подобъек-та), что отображается в окне Modifier Stack (Стеке Модификаторов). Если знак «+» возле названия модификатора отсутствует, то модификатор не допускает работу с подобъектным уровнем, и наоборот (рис. 4.06).


РИСУНОК 4.06. Выбор Подобъектного Уровня

Для удобства перехода в режим Sub-Object и обратно в контекстном меню выбранного объекта, вызываемого правым щелчком, содержится одноименный пункт (рис. 4.07).


РИСУНОК 4.07. Подобъектный Уровень в Контекстном Меню

Находясь в режиме Sub-Object можно также создавать Named Selection Set (Именованные Наборы) для подобъектов, но доступны они будут только в этом режиме.

Изображение:

Изображение:

6. Управление видимостью объектов

Управление видимостью объектов

В среде Мах разработана очень гибкая система управления видимостью объектов сцены. Кроме развитой системы команд существует набор дополняющих друг друга установок и настроек, позволяющих оптимизировать работу и «видеть» только те объекты или группы объектов, которые необходимы в данный момент. Особенно актуален вопрос видимости объектов в сложных насыщенных сценах, где иногда подолгу приходится ждать обновления (перерисовки) экрана (необходимо помнить что, все скрытые или замороженные объекты при этом игнорируются).

Все элементы управления видимостью сосредоточены в панели Display (Показ) и в Display Floater (Панели Показа) которую можно вызвать из падающего меню Tools (Инструменты).

Каждый из объектов сцены может иметь несколько уровней видимости:

  • Объект виден и в видовых экранах и при визуализации сцены.
  • Объект виден в видовых экранах, но не отображается и не участвует в визуализации сцены.
  • Объект виден в видовых экранах и отображается при обсчете сцены, но «заморожен» (недоступен) для команд выбора и редактирования.
  • Объект скрыт и не виден ни в видовых экранах, ни при визуализации.

Строго говоря, существут еще несколько вариантов видимости объектов, но они менее характерны и останавливаться на них не стоит.

Наиболее удобен способ управления объектами через Display Floater (Панель Показа), поэтому разберем его детальнее. Эта панель (рис. 4.08) состоит из двух закладок Hide / Freeze (Скрыть / Заморозить) и Object Level (Уровень Объекта).

Первая из них повторяет все основные команды панели Display за исключением некоторых редко используемых. Две группы рельефных кнопок отвечают за команды Hide (Скрыть) и Unhide (Показать), еще две - Freeze (Заморозить) и Unfreeze (Разморозить). Флажок Hide Frozen Object (Скрывать Замороженные Объекты) позволяет замораживать и скрывать объекты одновременно. Рельефные кнопки позволяют скрывать / замораживать Selected (Выбранные), Unselected (Невыбранные) объекты, осуществить выбор By Name (По Имени) и By Hit (По Щелчку).

Закладка Object Level (Уровень Объекта) управляет настройкой Hide By Category (Категориями Скрываемых Объектов) и набором флажков Display Properties (Показ Свойств Объекта). Панель Display Floater (Панель Показа) в любой момент может быть убрана с экрана (левым щелчком по кнопке закрытия) или повторно вызвана.

РИСУНОК 4.08. Плавающая Панель Показа

Изображение:

7. Клонирование объектов

Клонирование объектов

Существует несколько способов создавать копии объектов в Мах. Наиболее используемым является выделение копируемого объекта или группы объектов и применение одной из команд трансформации - Move (Переместить), Rotate (Повернуть) или Scale (Масштабировать) с нажатой клавишей . После завершения выполнения команды происходит вызов диалогового окна (рис. 4.09), где необходимо указать тип создаваемого объекта или группы объектов. Их существует три типа:


РИСУНОК 4.09. Выбор Режимов Клонирования

  • Сору (Копия) - новый объект наследует все свойства оригинала (геометрию, материалы, режимы отображения на видовых экранах и т.д.).

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

  • Instance (Экземпляр) - новый объект является полной копией исходного, и между ними создается следующая двусторонняя логическая связь: любые изменения оригинала сразу же отображаются во всех его экземплярах и наоборот.
  • Reference (Ссылка) - вариант экземпляра, но с односторонней связью. Только изменения оригинала влекут за собой такие же изменения во всех ссылках. Любое изменение ссылок объектов применяется только к конкретному модифицируемому объекту-ссылке.

Остается добавить, что окно Clone Options (Режимы Клонирования) позволяет задавать имя для создаваемых объектов в текстовом поле Name (Имя) и выбирать число новых копий счетчиком Number of copies (Число Копий).

Существует вариант клонирования объектов с использованием пункта Clone (Клонировать) в падающем меню Edit (Редактирование). Его использование вызывает такое же окно Clone Options (Режимы Клонирования), но без возможности изменить число создаваемых копий равное 1. Этот вариант создания копий объектов удобен, если копии должны иметь те же координаты, что и оригинал.

Еще один вариант клонирования состоит в использовании команд Mirror (Зеркало) и Array (Массив).

Первая из них вызывается кнопкой Mirror Selected Objects (Создать Зеркальное Отражение Объектов) из Дополнительное диалоговое окно Mirror: Screen Coordinates (Зеркало: Экранные Координаты) (рис. 4.10) позволяет выбрать ось копирования - X, Y, Z или плоскость копирования - XY, YZ, ZX.


РИСУНОК 4.10. Создание Зеркальных копий объектов

Положение переключателя Clone Selection (Клонировать Выделение) дает возможность выбрать тип создаваемых копий, причем положение No Clone (He Клонировать) выполняет зеркальное отображение исходного объекта, не создавая копий.

Команда Array (Массив) вызывается из списка кнопок, расположенных на панели инструментов Axis Constraints (Ограничения осей). Одноименное диалоговое окно Array позволяет задать способ копирования, размерность массива (1,2 или 3D), а также вид трансформации (Move, Rotate или Scale) которая будет применена к каждой копии (рис. 4.11).


РИСУНОК 4.11. Создание Массивов

Изображение:

Изображение:

Изображение:

Изображение:

8. Объединение объектов в группы

Объединение объектов в группы

Для облегчения управления наборами объектами и с целью упрощения насыщенных объектами сцен применяют команду Group (Сгруппировать). Ее вызов осуществляется через одноименный пункт падающего меню Group (Группировка) и применяется к выбранным объектам. Возникает окно ввода имени создаваемой группы (рис. 4.12). После подтверждения имени группы возникает новый объект сцены.


РИСУНОК 4.12. Набор имени группы

С объектами, объединенными по определенным критериям в группу (составные элементы сложного объекта, часто повторяющиеся наборы однотипных объектов и т. п..), очень удобно производить такие операции как выбор, клонирование, присвоение материалов, трансформации и многое другое. Группы могут иметь многоуровневую вложенную структуру. Рассмотрим возможности работы с группами объектов в среде Мах. Все команды управления сосредоточены в упоминавшемся ранее падающем меню Group (Группировка):

  • Group (Сгруппировать) - объединяет выбранные объекты в группу с новым именем, набираемым в одноименном диалоговом окне (рис. 4.12). Имя группы отображается жирным шрифтом в поле Name (Имя) или в квадратных скобках в диалоговом окне Select Objects (Выбор Объектов) (рис. 4.13).


РИСУНОК 4.13. Отображение групп в списках объектов

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

Close (Закрыть) - возвращает группу в стандартное состояние, скрывая объект с именем группы и возвращая полную группировку всем объектам группы.

  • Ungroup (Разгруппировать) - удаляет группировку объектов, входящих в выбранную группу, позволяя раздельную работу над каждым из них.
  • Explode (Полная Разгруппировка) - удаляет группировку объектов, составляющих многоуровневую, вложенную группу.
  • Detach (Отсоединить) - выделяет выбранный объект (или объекты) из состава группы. Для выполнения этой команды необходимо сначала открыть группу командой Open (Открыть).
  • Attach (Присоединить) - добавляет выбранные объекты в группу, указываемую левым щелчком мыши.

Изображение:

Изображение:

9. Трансформации объектов

Трансформации объектов

Виды Трансформаций

В среде Мах с любым объектом, набором нескольких объектов или группой можно производить три базовые операции преобразований - Move, Rotate и Scale (Перемещение, Поворот и Масштабирование), которые объединены одним общим термином - Transforms (Трансформации). Все трансформации назначены соответствующим кнопкам в Main Toolbar (Основной Панели), а Scale (Масштабирование) - списку кнопок. Преобразование перемещения позволяет изменять положение объекта в трехмерном пространстве, поворота -его ориентацию и масштабирования - линейные размеры объекта. Причем последнее преобразование может быть трех видов:

  • Uniform (Однородное) - равномерное масштабирование по трем координатным осям X,Y, Z;
  • Non-Uniform (Неоднородное) - выполняется по одной из осей или плоскостей объекта;
  • Squash (Сплющивание) - взаимно противоположное одновременное масштабирование по одной из осей и плоскости двух других, или наоборот.

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

Обычно выполнение преобразований с объектами сцены выполняется с приблизительной точностью («на глаз») в соответствии с визуальным восприятием положения, ориентации или масштаба. Однако, существуют случаи, когда необходим точный ввод параметров, для осуществления которого и служит способ Type-In (Точный Ввод). Соответствующее диалоговое окно может быть вызвано через пункт Transform Type-In (Точный Ввод Параметров Трансформаций) падающего меню Tools. В зависимости от типа выбранной трансформации, вызывается окно Move, Rotate или Scale Transform Type-In (Перемещение, Поворот или Масштабирование), которое содержит две группы счетчиков - Absolute: World (Абсолютные: Мировые Координаты) и Offset: Screen (Приращения: Экранные Координаты) (рис. 4.14).


РИСУНОК 4.14. Точный Ввод Параметров

Первоначально, при вызове этого окна в счетчиках первой группы отображаются точные значения положения выбранного объекта в трехмерном пространстве, его ориентация. При переключении на другой вид трансформаций (используя соответствующие модальные кнопки в Main Toolbar (Основной Панели) или через вызов контекстного меню редактируемого объекта) окно Type-In сразу же изменяется на соответствующее.

Дополнительными средствами, управляющими параметрами трансформаций в Мах, являются Restriction (Ограничения), задаваемые группой модальных кнопок, Reference Coordinate System (Координатная Система), выбираемая из списка кнопок. Все они расположены на панели инструментов Axis Constraints (Ограничения осей) (рис. 4.15). Еще один список кнопок Point Center (Центр Трансформаций), предназначенный для управления трансформациями, находится на Main Toolbar (Основной Панели).

РИСУНОК 4.15. Группа кнопок Ограничений Остановимся на каждом из них подробнее.