Перетащите мышкой из "команд" (рис.3) в нужное место на панели инструментов
Последние темы на форумах VOGBIT
03.10.2023 17:24:43
Здравствуйте!
Перетащите мышкой из "команд" (рис.3) в нужное место на панели инструментов |
|
|
|
19.10.2024 18:13:54
Здравствуйте! Пишу плагин. Есть вопросы по чтению и записи данных. К примеру, как получить список всех элементов номенклатуры (деталей), чтобы потом затолкать его в LookupEdit?
Изменено: |
|
|
|
19.10.2024 21:35:12
Здравствуйте!
|
|||
|
|
20.10.2024 14:41:09
С этим вопросом разобрался, спасибо)
|
|
|
|
06.03.2025 12:04:16
Подскажите пожалуйста, как добавлять заказ в разделе "Производственные заказы"?
Ну и соответственно назначать состав и технологию этому заказу. Хотелось бы автоматизировать то что сейчас делается руками, а именно: я создаю номенклатуру каждый раз новую (т.к. все заказы у нас разные), потом заказ, туда складываю эту номенклатуру и на каждую деталь назначаю операции из папки "Технология". Создавать папки и номенклатуры программно мы вобщем-то научились, а вот как заказ оформлять информации не нашли. |
|
|
|
07.03.2025 17:01:16
Здравствуйте,
Распишу по объектам в БД VOGBIT, что нужно по минимуму для такой задачи создавать в базе. Коллеги подскажут, если нужно, по коду, по тем моментам, которые, возможно, не ясны.
Для начала должна быть сама номенклатура (деталей, изделий), которую будем добавлять в производственный заказ. Если дальше цель стоит создать задания для производства по списку этой номенклатуры, то нужно для неё создать и заполнить техпроцесс. По минимуму для создания заданий нужны операции в техпроцессе и для операций должно быть указано место выполнения (участок) и Тшт. В принципе, по минимуму, этого достаточно. Разберем по шагам. Деталь – номенклатурная позиция. Техпроцесс детали – коллекция компонентов, у которой Owner = номенклатура «Деталь». Тип связи коллекции нужно поставить LT_ManProcess (здесь и далее везде пишу для используемых типов связей, параметров, статусов их идентификаторы). Обозначение коллекции ставьте любое, какое хотите. Статус ставьте тоже любой какой нравится, только НЕ ST_Invalid. Любой другой. Например, ST_Designing. Дальше добавляем в техпроцесс операции. Операция сама – это номенклатурная позиция. Находим нужную в справочнике и добавляем её, как компонент в коллекцию LT_ManProcess (техпроцесс детали). Тип связи компонента ставим LT_Operation. Количество и единицу измерения не заполняем для этого компонента, оставляем пустыми. Дальше нужно для операции задать место выполнения и трудоемкость. Место выполнения (участок), в принципе, у Вас может быть настроено в самом VOGBIT по умолчанию для «операции» в справочнике «Номенклатура». Тогда в техпроцессе уже указывать в явном виде его не нужно, при формировании заданий «подхватится» настроенный по умолчанию участок. Чтобы указать в явном виде для операции место выполнения в техпроцессе, находим в справочнике «Подразделения» нужный производственный участок и добавляем его к компоненту LT_Operation (операции) в коллекции LT_ManProcess (в техпроцессе), как связанный объект с типом связи LT_Place. Если вы используете пооперационное нормирование, то чтобы потом создались задания для производства, нужно ещё добавть хоть какую-нибудь «Трудоемкость» к операции. Для этого добавьте параметр T_OPR_HOUR (float) к компоненту LT_Operation (операции) в коллекции LT_ManProcess (в техпроцессе), значение = Тшт в часах. Всё, по минимуму – достаточно. Т.е. создаете номенклатуру деталей. К каждой детали коллекцию LT_ManProcess (техпроцесс), в неё добавляете нужные компоненты LT_Operation (операции), к каждому такому компоненту добавляете связанный объект LT_Place (подразделение, участок), и параметр T_OPR_HOUR (трудоемкость). На этом то, что вставлять в «заказ» у нас есть. Переходим к созданию и заполнению «Производственного заказа». Создаёте номенклатурную позицию – «Заказ». Обозначение и наименование – по Вашему усмотрению. Для этой номенклатурной позиции создаёте коллекцию компонентов LT_MAN_CHART (тех. карта заказа). Обозначение коллекции ставьте любое, какое нравится, статус ставьте ST_InWork (с любым другим её не будет видно в окне «Производственные заказы»). В эту коллекцию LT_MAN_CHART добавляете из номенклатуры созданные нами ранее «Детали», как компоненты. Тип связи при этом можете использовать, в принципе, почти какой хотите, тут нет особых ограничений, но стандартно используется LT_Product (изделие). В некоторых случаях - LT_Part (деталь), LT_Assemble_Unit (сборочная единица). Обязательно поставьте для компонентов в коллекции LT_MAN_CHART (позиций в карте заказа) количество и единицы измерения (в подавляющем большинстве случаев ставится «шт»). В принципе, вроде, всё. Таким образом у Вас получится заказ, тех. карта заказа, в ней детали с указанием количества, у деталей техпроцессы с операциями. Для того, чтобы «запустить в производство» по самому минимуму достаточно. А дальше уже можно этот «скелет» наращивать «мясом» по мере надобности, в зависимости от задачи.
P.S. В заключении вставлю свои 5 копеек… Для пользователей, у которых «каждый новый заказ – это новая номенклатура», но при этом само производство довольно простое, в современных версиях VOGBIT есть некоторое количество штатных, встроенных функций, которые довольно сильно зачастую облегчают жизнь простым пользователям, без необходимости прибегать к программированию. Например:
Вот эти вещи есть в VOGBIT (в последних версиях) уже готовые, "из коробки". |
|
|
|
10.03.2025 14:55:27
Доброго времени суток. Набросал код, три основных вопроса:
1. Правильные ли объекты я использую 2. Правильно ли добавляю компонент в коллекцию 3. В какой папке должна создаваться номенклатура заказа, которая будет потом видна во вкладке 'Производственные заказы' //-------------------------------------------- var mainID = 157194; // ID папки 'Основная' var ordersID = 555555; // ID папки 'Заказы' var tokarkaID = 666666; // ID номенклатуры 'Токарка' // Создаем папку заказчика Folder newFolder = ExtApp.Application.General.Folders(mainID).AddNew(); newFolder.Name.Value = "Роскосмос"; newFolder.ParentID.Value = ordersID; newFolder.Save(); // Создаем номенклатуру в этой папке var nmk = ExtApp.Application.General.Nomenclature(newFolder.ID.AsLongInt, CatalogOptions.None).AddNew(); nmk.Notation.Value = "DRAW.001.01"; nmk.Name.Value = "Фланец"; nmk.Save(); // Дальше не знаю, на ощупь писал ComponentCollection collection = new ComponentCollection(); collection.LinkTypeNotation.Value = "LT_ManProcess"; collection.StatusNotation.Value = "ST_Designing"; collection.Notation.Value = "Техпроцесс"; Components component = new Components(); component.OwnerID.DefaultValue = collection.ID.AsLongInt; // Компонент в коллекцию так добавляется? component.LinkTypeNotation.DefaultValue = "LT_Operation"; component.Params["T_OPR_HOUR "].Value = 1; component.SourceNomenclatureID.DefaultValue = tokarkaID; // Создаём номенклатуру заказа // Дальше ключевой вопрос - где создавать номенклатуру? var zkz = ExtApp.Application.General.Nomenclature(КАКОЙ ID СЮДА ПИСАТЬ?, CatalogOptions.None).AddNew(); //--------------------------------------------
Изменено: |
|
|
|
10.03.2025 16:47:45
Коллекция. На входе номенклатура для которой создаётся ТП:
Компонент. На входе Id ТП и Id номенклатуры операции (в вашем случае tokarkaID):
|
|||||||||
|
|
11.03.2025 12:43:21
Не может почему-то присвоить ID, из-за чего так может быть?
void ExampleButtonActionExecute(object sender, ActionExecuteEventArgs e) { // ID 157337 - LT_ManProcess // ID 157141 - LT_Operation // ID 157138 - LT_MAN_CHART // ID 157720 - LT_Part // // ID 157205 - ST_Designing // ID 157206 - ST_InWork // // ID 157325 - T_OPR_HOUR // ID 159751 - VGB_Quantity long nmkID = 227610; // ID нашей детали 'Фланец' long oprID = 203301; // ID операции 'Токарная' long manID = CreateManProcess(nmkID, 157337, 157205); long comID = AddComponent(manID, oprID, 157141); AddObjectParameter(comID, 157325, 1); var zkz = ExtApp.Application.General.Nomenclature(-1, CatalogOptions.None).AddNew(); zkz.Notation.Value = "1863 Роскосмос - Фланец"; // Наименование заказа var zkz_manID = CreateManProcess(zkz.ID.AsLongInt, 157138, 157206); var zkz_comID = AddComponent(zkz_manID, nmkID, 157720); AddObjectParameter(zkz_comID, 159751, 1); } long CreateManProcess(long nmkId, long linkID, long statusID) { var cc = ExtApp.Application.General.ComponentCollections(nmkId).AddNew(); try { cc.Notation.Value = "Техпроцесс"; cc.LinkTypeID.Value = linkID; cc.StatusID.Value = statusID; cc.Save(); } finally { cc.Cancel(); } return cc.ID.AsLongInt; } long AddComponent(long collectionId, long compNmkId, long linkID) { var comp = ExtApp.Application.General.Components(collectionId).AddNew(); try { comp.NomenclatureID.Value = compNmkId; comp.LinkTypeID.Value = linkID; comp.Save(); } finally { comp.Cancel(); } return comp.ID.AsLongInt; } ObjectParameter AddObjectParameter(long objectId, long parameterID, object parameterValue) { var objParam = ExtApp.Application.General.ObjectParameters(objectId).AddNew(); try { objParam.ParameterID.Value = parameterID; objParam.ParameterValue.Value = parameterValue; objParam.Save(); } finally { objParam.Cancel(); } return objParam; }
Изменено: |
|
|
|
11.03.2025 16:20:45
|
|||
|
|
12.03.2025 12:32:35
Всех благодарю! У меня получилось создать заказ.
Хотелось бы ещё подсказку как удалить созданный мною заказ, т.к. при отладке плагина буду туда-сюда создавать один и тот же тестовый заказ и удалять его. И у меня нарисовалась проблемка, я прогнал тот же код что выше (заказ который создал - удалил перед этим вручную), только вместо статуса ST_InWork поставил ST_MAN_3, в надежде что таким образом сразу создадутся задания, но по итогу номенклатура уплыла в неизвестном направлении. Я решил найти её циклом и нашёл, но удалить не вышло. В Point_1 и Point_2 заходит, в Point_3 нет. foreach(var nmk in ExtApp.Application.General.Nomenclature(-1, CatalogOptions.None)) { if(!nmk.Notation.IsNull) { if((string)nmk.Notation.Value == "1863 Роскосмос - Фланец") { System.Windows.Forms.MessageBox.Show("Point_1"); foreach (var com in ExtApp.Application.General.ComponentCollections(nmk.ID.AsLongInt)) { System.Windows.Forms.MessageBox.Show("Point_2"); // foreach (var prm in ExtApp.Application.General.Parameters(com.ID.AsLongInt, CatalogOptions.None)) // не заходит в цикл // foreach (var prm in ExtApp.Application.General.Components(com.ID.AsLongInt, CatalogOptions.None)) // не заходит в цикл // foreach (var prm in ExtApp.Application.General.LinkedObjects(com.ID.AsLongInt)) // не заходит в цикл // foreach (var prm in ExtApp.Application.General.ObjectParameters(com.ID.AsLongInt)) // не заходит в цикл // foreach (var prm in ExtApp.Application.General.ComponentCollections(com.ID.AsLongInt)) // ссылка на объект не указывает на экземпляр объекта // com.Count == 27 foreach (var prm in ExtApp.Application.General.ObjectParameters(com.ID.AsLongInt)) { System.Windows.Forms.MessageBox.Show("Point_3"); } com.Delete(); // Коллекция компонентов либо не существует, либо содержит компоненты. } nmk.Delete(); break; } } }
Изменено: |
|
|
|
12.03.2025 16:27:15
Думаю, что заходит и выходит т.к. набор данных пустой.
|
|||||||||||||
|
|
12.03.2025 16:36:38
Не вижу смысла писать в таком случае свои "удалялки". Потеря времени. Проще и быстрее штатными функциями все поудалять в данном конкретном случае. Не так много насоздавали.
В сообщении #67 я Вам расписал кто как с кем связан в плане объектов в БД при создании. Удалять, как в любой базе данных, нужно "с конца". Вы создали номенклатурную позицию (Заказ), к ней коллекцию компонентов (Карта заказа), в эту коллекцию добавили компоненты (Детали в карту заказа). Номенклатура не удалится, пока у неё есть коллекции, коллекция не удалится пока в ней есть компоненты. Соответственно, чтобы штатными средствами всё удалить: 1. Идем в общий справочник "Коллекции компонентов", находим там коллекцию - созданную Вами тех. карту (обычным поиском или авто-фильтром - по имени, по типу связи, как удобнее). 2. Открываем для этой коллекции зависимое окно "Компоненты". Всё там выделяем и удаляем. 3. Удаляем саму коллекцию (1). 4. Идем в общий справочник "Номенклатура", там (поиском, авто-фильтром, по обозначению или наименованию) находим созданную Вами номенклатуру "заказ". И удаляем её. Всё. Готово. По-моему проще руками так сделать в данном конкретном случае, чем "удалялки" писать. Кстати, "Папка", куда складывать номенклатурную позицию "заказ" и коллекцию "карта заказа", что Вы спрашивали в сообщении #68 - они как раз и нужны, чтобы в случае задачи а-ля п. (1) и (4) искать не поиском по всему справочнику то, что вы насоздавали, а оно сразу лежало в конкретной папке и там вы его сразу и нашли при необходимости. Без папки поиском тоже найдётся. Но когда изначально известно, где лежит - проще. Есть ещё админская утилита "Очистки заказов". Можно после п.(1), как альтернативный вариант вместо п. (2) и (3), встать в справочнике на нужную коллекцию (карту заказа, которую Вы создали) и в меню нажать "Настройка" - "Очистка заказов". Эта штука удаляет все из коллекции и саму коллекцию. Но более актуальна она, когда кроме деталей (компонентов) там ещё много чего есть (партии, назначенные ТП и т.д.). Чтобы руками всё это не удалять. В Вашем текущем случае - и руками, в принципе, не долго. Но можно и утилиту "Очистка заказов" задействовать. Готовая "удалялка" для "карт заказов".
![]()
|
|||||
|
|
22.07.2025 13:52:30
Добрый день! Нам всё таки понадобилась свойская удалялка. Внесли большой заказ, но часть номенклатур оказалась не корректной, замаялись удалять их вручную. В виде мусорных данных их там оставлять было не желательно. Я составил ф-цию удаления номенклатуры, но работает она как-то непонятно. Постоянно ругается на состояние объекта. Мне нужно чтобы ф-ция работала без багов, не вылетала. Смотрит плагин допустим по файловой системе или по списку какому-нибудь, ага - эту удалить надо со всеми её ветками и коллекциями, удалил и дальше пошел.
|
|||
|
|
22.07.2025 17:32:08
Вариант 1: foreach заменить на for. Получится что-то типа:
PS2. Безотносительно к Вогбиту, я бы не рекомендовал использовать foreach для изменения коллекции внутри итерации |
|||||
|
|
05.08.2025 11:12:42
Здравствуйте, подскажите пожалуйста как работать с ExecutingHistoryRecord, и вообще что такое BizObject, это вроде, как я понял, номенклатуры, только какой-то более обобщённый объект. По мере развития нашего плагина, понадобилось залезть в состояние выполнения работ, только как это сделать не совсем понятно. Нам хотелось бы программно получать историю работ на конкретный компонент из заказа.
|
|||
|
|
05.08.2025 17:54:05
Здравствуйте!
Тут надо понимать, что форма "История выполнения работ", которая у Вас на картинке - это, мягко говоря, совсем не "Номенклатура" какая-нибудь. Если в формах типа "Номенклатура", "Подразделения" и т.п. просто, грубо говоря, что в таблице в базе лежит, то и выводится в виде колонок в гриде (утрированно), то тут сначала запросом добываются данные, из разных мест: из Task'ов, плановых трудовых ресурсов, фактических трудовых ресурсов, параметров и др. Причем в зависимости, например, от "уровня учёта" там из разных мест может добываться то, что в форме выводится в одной и той же колонке. И по "+" в этой форме совсем не "строчка" добавляется в некую "табличку", а создаётся куча разных объектов, перевязывается между собой: Task'и, параметры для них, заполняются плановые и фактические трудовые ресурсы и т.д. ещё много чего. И там навешена попутно в этом процессе куча логики. Когда можно создавать, когда нельзя. Что именно создавать в какой ситуации. Что дальше ещё делать после того, как создали (например, если это "объединенное задание", то там ещё множество действий производится с теми, кого оно "объединяет"). В каком случае менять статусы, в каком не менять, на какой статус менять, кому статус менять. И т.д. и т.п.... В общем, такие формы - это уже, мягко говоря, не "Номенклатура", куда можно просто "добавить запись". Тут все сильно сложнее. Лезть туда самостоятельно без какой-то уж совсем крайней в этом необходимости настоятельно не рекомендуется. Отсюда и вопрос: Зачем? |
|||
|
|
05.08.2025 18:12:56
Там есть в общем случае: участок, операция (номер, название, комментарий), дата, смена, количество (сданное), фио работника, нормо-часы, время начала и окончания работ (не всегда, только в определенных случаях), признаки разные (по техпроцессу/не по техпроцессу задание выполнялось, наладка это была станка или изготовление деталей на уже налаженном станке), кто выдал задание/кто принял задание (не во всех случаях, только в некоторых это есть), разные комментарии, может быть (не всегда) станок, на котором выполнялось, может быть "пост" (при "высоком/максимальном" уровне). И ещё ряд вещей, но они уже используются только в некоторых достаточно "экзотических" случаях. Что конкретно из этого вы хотите добыть программно? Какой "уровень" вы используете? Одинаковый ли он у Вас для всех заданий, или разный, например, для разных "участков"? Используете ли вы "объединённые" задания, или нет? |
|||
|
|
13.08.2025 08:51:40
Мы в принципе решили ту задачу при помощи костылей и штатными средствами. Надо было поправить заказ, номенклатуры по внешнему списку, заказ в работе уже был и он на 700+ строк, а внесли мы его на скорую руку. Мы работаем на среднем уровне, задания не объединяем.
Вообще в этот раз я хотел бы поподробнее узнать про объект BizObject, что он из себя представляет, во что его можно конвертировать / преобразовывать. |
|
|
|
13.08.2025 19:00:02
BizObject - это абстрактный класс от которого унаследованы основные классы (номенклатура, компонент, задание, документ и т.д.)
В данном случаем объектом является BizObject из BizObjectList'a. BOL был получен в результате выполнения запроса с использованием ExtensibleApplication.Application.ExecuteQuery(query). Пример с запросом есть на первой странице темы. |
|
|
|
14.08.2025 10:35:36
Есть вот такая строка:
Чем отличается BizObjectList от BizObject[] ? Если перебирать их циклом foreach отличия будут какие-нибудь?
Изменено: |
|||
|
|
14.08.2025 12:55:21
BizObjectList согласованно загружается из БД и сохраняет в БД измененные BizObject'ы. BizObjectList имеет такие методы, как AddNew(), DeleteAll(), SaveAll() и.т.д. для изменения и сохранения набора и т.д. В том числе BizObjectList реализует интерфейсы для перебирания содержащихся в нем BizObject'ов по индексу (цикл for) или с помощью энумератора (цикл foreach). А BizObject[] - это просто массив со ссылками на объекты BizObject из BizObjectList. Как у любого массива, элементы можно перебрать с помощью циклов foreach или for. При этом удаление элемента из этого массива, например, удаляет только ссылку, но не сам BizObject, массив - это просто копия ссылок на объекты. |
|||||
|
|
18.08.2025 12:19:34
Благодарю за развёрнутый ответ, что-то вроде этого я и хотел узнать, потихоньку по крупицам выстраивается у меня в голове концепция ваших API.
Теперь пытаюсь подгрузить материал в номенклатуру, но похоже что не всё правильно делаю. Есть у нас в базе значит номенклатура материала, ну я её и добавляю как компонент в коллекцию LT_ManProcess и ставлю компоненту статус LT_Material. Смотрю результат, вроде похоже, но не очень. В отличие от добавления вручную, строка не жирным шрифтом написана и расположена снизу, а не сверху. Как по нормальному сделать? И второй вопрос: не могу почему-то удалить материал из тех-процесса строкой:
|
|||
|
|
18.08.2025 17:28:20
Технически "основной материал" выделяется следующим образом. Берется компонент "материал" из техпроцесса и приделывается, как связанный объект к номенклатуре детали. То есть, чтобы "строчка стала жирной" нужно после
Будьте внимательны! Во-первых, не приделайте случайно что-нибудь не то или не туда. Во-вторых, следите, чтобы не получилось ни в коем случае в результате действий вашего кода, например, более одного связанного объекта LT_Material у номенклатурной позиции детали. Чревато последствиями весьма неприятными и в самых на первый взгляд неожиданных местах.
Удалить компоненты из коллекции можно только в том случае, если к этим компонентам ничего не приделано (параметры, связанные объекты), они сами никуда не приделаны (как связанные объекты, например) и нигде не задействованы (например, "операции" могут быть задействованы в "запланированных этапах" и в "завершенных этапах" в "заданиях"). |
|||||||||
|
|
19.08.2025 08:45:14
Так пойдёт?
Изменено: |
|||||||
|
|
19.08.2025 15:56:56
Связанные объекты - это механизм для установки в программе взаимосвязи любых двух объектов. Можно сказать, что "Объект Б" является связанным объектом "Объекта А". Используется данный механизм в плагинах очень много для чего и в разных местах.
Тип связи - определяет "как" связан в данном случае "Объект Б" с "Объектом А". Можно так сказать, тип связи определяет смысл этой связи. Что именно означает в данном конкретном случае эта связь между "А" и "Б". Кроме того что тип связи используется при связывании объектов, чтобы указать в чем смысл соответствующей связи, он может существовать и как отдельное самостоятельное свойство у разных объектов. Например, у компонентов в коллекции, у расчётных документов, у учётных документов, у заданий. Общий смысл тот же самый. С помощью типа связи можно указать, что именно это за компонент, документ, задание. Дальше уже в плагинах строить на этом какую-то свою логику. На уровне самой базы данных, какой "тип связи" - не влияет ни на что. Какой хочешь такой и ставь. Дальше всё зависит от логики плагинов. Как они обрабатывают эту информацию, для чего используют.
Если исходя из задачи, например, посмотреть в окне самого VOGBIT'а связанный файл, то да. Все равно какой тип связи. А если исходя из задачи, к примеру, чтобы у оператора машины резки листового металла в момент взятия в работу задания на цеховом терминале в некоей заданной папке в сети появилась автоматически программа резки соответствующая, а потом после выполнения задания она автоматически из этой папки исчезла - вот тут совсем не все равно какой файл с каким типом связи "приделан к номенклатуре". Так что тут всё от задачи зависит... |
||||
|
|
|||