Rак поменять переменные сборки ?

Автор Hafry, 20.11.25, 11:28:53

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

Hafry

Люди добрые подскажите, что я делаю не так?
Смотрю официальную SDK, и вроде делаю все как надо, но при этом значения в сборке не меняются, с чем это связано?
Прикрепляю фото, какие переменные я хочу изменить

Вот код:
using Kompas6API5;
using Kompas6Constants;
using Kompas6Constants3D;
using System;
using System.Runtime.InteropServices;

namespace KompasTest
{
    class Program
    {
        static void Main()
        {
            // === 1. Подключаемся к КОМПАС-3D ===
            KompasObject kompas = ConnectKompas();
            if (kompas == null)
                throw new Exception("Не удалось получить KompasObject.");

            kompas.Visible = true;
            kompas.ActivateControllerAPI();

            // === 2. Путь к модели ===
            string modelPath =
                @"C:\Users\admin\Downloads\Telegram Desktop\Макрос компас\Сборка.a3d";

            // === 3. Открываем 3D-документ через API5 ===
            ksDocument3D doc3D = (ksDocument3D)kompas.Document3D();
            if (doc3D == null)
            {
                Console.WriteLine("ksDocument3D == null");
                return;
            }

            if (!doc3D.Open(modelPath, false))
            {
                Console.WriteLine("Не удалось открыть документ: " + modelPath);
                return;
            }

            // === 4. Работа с переменными (логика из примера) ===
            GetSetArrayVariable(kompas, doc3D);

            Console.WriteLine("Готово. Нажмите Enter для выхода...");
            Console.ReadLine();
        }

   
        private static void GetSetArrayVariable(KompasObject kompas, ksDocument3D doc)
        {
            // Проверяем, что документ – сборка
            if (doc.IsDetail())
            {
                kompas.ksError("Текущий документ должен быть сборкой");
                return;
            }

            ksPart part = (ksPart)doc.GetPart((int)Part_Type.pTop_Part);
            if (part == null)
            {
                kompas.ksMessage("Не удалось получить верхний уровень сборки (ksPart).");
                return;
            }

            ksVariableCollection varCol = (ksVariableCollection)part.VariableCollection();
            if (varCol == null)
            {
                kompas.ksMessage("Не удалось получить VariableCollection.");
                return;
            }

            varCol.refresh();  // обновляем список переменных

            int count = varCol.GetCount();
            //if (count == 0)
            //{
            //    kompas.ksMessage("В сборке нет переменных.");
            //}

            // Значения, которые хотим установить
            double set_A = 900;
            double set_B = 700;
            double set_C = 300;

            // Структура переменной
            ksVariable var = (ksVariable)kompas.GetParamStruct((short)StructType2DEnum.ko_VariableParam);
            if (var == null)
            {
                kompas.ksMessage("Не удалось получить ksVariable через GetParamStruct.");
                return;
            }

            string buf;

            // --- Первый проход: показать и при необходимости изменить ---
            for (int i = 0; i < count; i++)
            {
                var = (ksVariable)varCol.GetByIndex(i);
                if (var == null)
                    continue;

                buf = string.Format(
                    "Номер переменной: {0}\nИмя: {1}\nЗначение: {2}\nКомментарий: {3}",
                    i, var.name, var.value, var.note
                );
                kompas.ksMessage(buf);
                // Здесь меняем A, B, C по имени
                if (string.Equals(var.name, "A", StringComparison.OrdinalIgnoreCase))
                {
                    var.value = set_A;
                    var.note = "Установлено из макроса (A)";
                }
                else if (string.Equals(var.name, "B", StringComparison.OrdinalIgnoreCase))
                {
                    var.value = set_B;
                    var.note = "Установлено из макроса (B)";
                }
                else if (string.Equals(var.name, "C", StringComparison.OrdinalIgnoreCase))
                {
                    var.value = set_C;
                    var.note = "Установлено из макроса (C)";
                }

                //Пример из документации — поменять первую попавшуюся переменную
                // if (i == 0)
                //{
                //    var.note = "qwerty";
                //    double d = 0;
                //    kompas.ksReadDouble("Введи переменную", 10, 0, 100, ref d);
                //    var.value = d;
                //}
            }

            // --- Второй проход: показать уже изменённые значения ---
            for (int j = 0; j < count; j++)
            {
                var = (ksVariable)varCol.GetByIndex(j);
                if (var == null)
                    continue;

                buf = string.Format(
                    "ПОСЛЕ ИЗМЕНЕНИЯ:\nНомер: {0}\nИмя: {1}\nЗначение: {2}\nКомментарий: {3}",
                    j, var.name, var.value, var.note
                );
                kompas.ksMessage(buf);
            }

            // Перестраиваем модель
            part.RebuildModel();
            doc.RebuildDocument();

            kompas.ksMessage("Переменные обработаны, модель перестроена.");
        }

     
        private static KompasObject ConnectKompas()
        {
            KompasObject kompas = null;

            try
            {
                kompas = (KompasObject)Marshal.GetActiveObject("KOMPAS.Application.5");
            }
            catch
            {
                Type type = Type.GetTypeFromProgID("KOMPAS.Application.5");
                if (type == null)
                    return null;

                kompas = (KompasObject)Activator.CreateInstance(type);
            }

            return kompas;
        }
    }
}

p3452

 :cl:
И зачем ТАКОЙ "огород"?
ksVariable var = (ksVariable)varArr.GetByName(varName, true, false); // varName - текущая переменная

Hafry

это ты к чему?
Я делал по примеру, потом начал играться с переменными, но в итоге ничего не получается


просто такой код в сдк

void GetSetArrayVariable()
    {
      if (doc.IsDetail())
      {
        kompas.ksError("Текущий документ должен быть сборкой");
        return;
      }
      ksPart part = (ksPart)doc.GetPart(0);  // первая деталь в сборке
      if (part != null)
      {
        // работа с массивом внешних переменных
        ksVariableCollection varCol = (ksVariableCollection)part.VariableCollection();
        if (varCol != null)
        {
          ksVariable var = (ksVariable)kompas.GetParamStruct((short)StructType2DEnum.ko_VariableParam);
          if (var == null)
            return;
          for (int i = 0; i < varCol.GetCount(); i ++)
          {
            var = (ksVariable)varCol.GetByIndex(i);
            buf = string.Format("Номер переменной {0}\nИмя переменной {1}\nЗначение переменной {2}\nКомментарий {3}", i, var.name, var.value, var.note);
            kompas.ksMessage(buf);
            if (i == 0)
            {
              var.note = "qwerty";
              double d = 0;
              kompas.ksReadDouble("Введи переменную", 10, 0, 100, ref d);
              var.value = d;
            }
          }
     
          for (int j = 0; j < varCol.GetCount(); j ++)
          {
            // просмотр изменненных переменных
            var = (ksVariable)varCol.GetByIndex(j);
            buf = string.Format("Номер переменной {0}\nИмя переменной {1}\nЗначение переменной {2}\nКомментарий {3}", j, var.name, var.value, var.note);
            kompas.ksMessage(buf);
          }
          part.RebuildModel();  // перестроение модели
        }
      }
    }

p3452

Постарайтесь ОСМЫСЛИТЬ, хотя бы одну строчку кода - она стоит всего Вашего "огорода"...
+ Благодарностей: 1

Hafry

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

вот код:
using Kompas6API5;
using Kompas6Constants;
using Kompas6Constants3D;
using System;
using System.Runtime.InteropServices;



namespace KompasTest
{
    class Program
    {
        static void Main()
        {
            // === 1. Подключаемся к КОМПАС-3D ===
            KompasObject kompas = ConnectKompas();
            if (kompas == null)
                throw new Exception("Не удалось получить KompasObject.");

            kompas.Visible = true;
            kompas.ActivateControllerAPI();

            //Путь к модели
            string modelPath =
                @"C:\Users\admin\Downloads\Telegram Desktop\Макрос компас\сборка.a3d";

            //Открываем 3D-документ через API5
            ksDocument3D doc3D = (ksDocument3D)kompas.Document3D();
            if (doc3D == null)
            {
                Console.WriteLine("ksDocument3D == null");
                return;
            }

            if (!doc3D.Open(modelPath, false))
            {
                Console.WriteLine("Не удалось открыть документ: " + modelPath);
                return;
            }

            //Работа с переменными
            GetSetArrayVariable(kompas, doc3D);

            Console.WriteLine("Готово. Нажмите Enter для выхода...");
            Console.ReadLine();
        }


        private static void GetSetArrayVariable(KompasObject kompas, ksDocument3D doc)
        {
            if (doc.IsDetail())
            {
                kompas.ksError("Текущий документ должен быть сборкой");
                return;
            }

            ksPart part = (ksPart)doc.GetPart((int)Part_Type.pTop_Part);
            if (part == null)
            {
                kompas.ksMessage("Не удалось получить верхний уровень сборки (ksPart).");
                return;
            }

            ksVariableCollection varCol = (ksVariableCollection)part.VariableCollection();
            if (varCol == null)
            {
                kompas.ksMessage("Не удалось получить VariableCollection.");
                return;
            }

            varCol.refresh();

            double set_A = 900;
            double set_B = 700;
            double set_C = 300;

            ksVariable varA = (ksVariable)varCol.GetByName("A ", true, true);
            ksVariable varB = (ksVariable)varCol.GetByName("B ", true, true);
            ksVariable varC = (ksVariable)varCol.GetByName("C ", true, true);

            string notFound = "";
            if (varA == null) notFound += "A ";
            if (varB == null) notFound += "B ";
            if (varC == null) notFound += "C ";

            if (!string.IsNullOrEmpty(notFound))
            {
                kompas.ksMessage("Не найдены переменные: " + notFound);
                return;
            }

            varA.value = set_A;
            varB.value = set_B;
            varC.value = set_C;

            part.RebuildModel();
            doc.RebuildDocument();

            kompas.ksMessage("Переменные A, B, C обновлены, модель перестроена.");
        }


        private static KompasObject ConnectKompas()
        {
            KompasObject kompas = null;

            try
            {
                kompas = (KompasObject)Marshal.GetActiveObject("KOMPAS.Application.5");
            }
            catch
            {
                Type type = Type.GetTypeFromProgID("KOMPAS.Application.5");
                if (type == null)
                    return null;

                kompas = (KompasObject)Activator.CreateInstance(type);
            }

            return kompas;
        }
    }
}


pas2h

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

Цитата: Hafry от 20.11.25, 15:23:10ksVariable varA = (ksVariable)varCol.GetByName("A ", true, true);
            ksVariable varB = (ksVariable)varCol.GetByName("B ", true, true);
            ksVariable varC = (ksVariable)varCol.GetByName("C ", true, true);
+ Благодарностей: 1

Hafry

У меня пробелы в начале не стояли, что так, что так не ворк

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

Если поможете буду очень сильно благодарен!!!

p3452

Ничего удивительного, закономерный результат, если Ваши переменные не ВНЕШНИЕ!

Правой кнопкой мышки на каждой переменной и выставить "флаг" - Внешняя. После этого Ваш код выполнится...
+ Благодарностей: 1

pas2h

Ниже вполне себе рабочий код под Вашу задачу (сборка должна быть активной вкладкой):

using Kompas6API5;
using KompasAPI7;
using System;



namespace KompasTest
{
    class Program
    {
        static KompasObject kompas;     //Интерфейс приложения в API5
        static IApplication appl;       //Интерфейс приложения в API7     
        static IKompasDocument3D doc3D; //Интерфейс документа 3D в API7

        static void Main(string[] args)
        {
            if (kompas == null)
            {
                Type t = Type.GetTypeFromProgID("KOMPAS.Application.5");
                kompas = (KompasObject)System.Runtime.InteropServices.Marshal.GetActiveObject("KOMPAS.Application.5");
            }

            if (kompas != null)
            {
                kompas.Visible = true;
                kompas.ActivateControllerAPI();
            }

            // Получаем интерфейс приложения в API7
            appl = (IApplication)kompas.ksGetApplication7();
            if (appl == null)
                return;

            //Выполнение основной части программы
            if (kompas != null)
            {
                doc3D = (IKompasDocument3D)appl.ActiveDocument;
                IPart7 cPart3D = doc3D.TopPart;
                IFeature7 cFeat = (IFeature7)cPart3D;

                //ищем переменные
                IVariable7 varA = cFeat.Variable[false, true, "A"];
                IVariable7 varB = cFeat.Variable[false, true, "B"];
                IVariable7 varC = cFeat.Variable[false, true, "C"];

                //проверяем, что не найдено.
                //в противном случае присваиваем нужное значение
                double set_A = 900;
                double set_B = 700;
                double set_C = 300;

                string notFound = "";
               
                if (varA == null)
                    notFound += "A ";
                else
                    varA.Value = set_A;
                if (varB == null)
                    notFound += "B ";
                else
                    varB.Value = set_B;
                if (varC == null)
                    notFound += "C ";
                else
                    varC.Value = set_C;
                if (!string.IsNullOrEmpty(notFound))
                {
                    kompas.ksMessage("Не найдены переменные: " + notFound);                   
                }

                doc3D.RebuildDocument();
            }
        }
    }
}
+ Благодарностей: 1

Hafry

спасибо вам обоим за помощь!!
Теперь все ворк и первый вариант, и второй

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

Подскажите, чем отличается тогда АПИ7 от АПИ5, раз оба решения есть и там, и там
+ Благодарностей: 1

p3452

Цитата: Hafry от 21.11.25, 10:50:20Подскажите, чем отличается тогда АПИ7 от АПИ5, раз оба решения есть и там, и там
1. Многим!
2. API не всегда дублируют возможности друг друга...
3. Из практики:
  - Приоритет отдаем API7, если отсутствует нужный функционал, используем API5.
  - Есть функции конвертации API из одного в другой.
  - Код на API5, в большинстве случаем, короче.

+ Благодарностей: 1

Hafry

понял!
Как интересно будет копаться во всем этом
еще раз спасибо!)