C#. Передать для выполнения значение локальной переменной AutoCAD.
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > .NET > C#. Передать для выполнения значение локальной переменной AutoCAD.

C#. Передать для выполнения значение локальной переменной AutoCAD.

Ответ
Поиск в этой теме
Непрочитано 06.04.2025, 13:41 #1
C#. Передать для выполнения значение локальной переменной AutoCAD.
sathalex
 
Регистрация: 02.07.2014
Сообщений: 59

Привет.
Пытаюсь написать функцию, которая будет считывать из файла .XML (полученного путем экспорта поверхности из Civil 3D) номера точек.
Вообщем-то функция готова и рабочая. Но не могу ей передать путь к файлу .xml, из которого нужно извлечь номера точек. Путь файла хранится в локальной переменной AutoCAD filepathxml.
Сейчас этот момент реализован путем считывания пути из файла .ini, который я создаю в папке с моим .dll. Но это очень неудобно.
Так же функция возвращает после выполнения в командную строку AutoCAD список номеров точек, которые по итогу мы извлекли из файла .xml.
Так же не могу понять, как мне этот список назначить локальной переменной для дальнейшей работы с ним.


Код:
[Выделить все]
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;

public class PointIdExtractor
{
    [CommandMethod("GetPointIds")]
    public static void GetPointIdsCommand()
    {
        Document doc = Application.DocumentManager.MdiActiveDocument;
        Editor ed = doc.Editor;

        try
        {
            // Получаем путь из конфигурационного файла
            string filePath = GetFilePathFromConfig();

            if (string.IsNullOrEmpty(filePath))
            {
                ed.WriteMessage("\nОшибка: Не удалось получить путь к файлу из конфигурации");
                return;
            }

            if (!File.Exists(filePath))
            {
                ed.WriteMessage($"\nОшибка: Файл не найден по пути: {filePath}");
                return;
            }

            List<int> ids = GetPointIdsFromFile(filePath);

            // Форматируем вывод в виде (1 2 3 4 5 ...)
            ed.WriteMessage($"\nНайдено ID точек: {FormatAsLispList(ids)}");
        }
        catch (System.Exception ex)
        {
            ed.WriteMessage($"\nОшибка: {ex.Message}");
        }
    }

    private static string GetFilePathFromConfig()
    {
        try
        {
            // Путь к конфигурационному файлу рядом с DLL
            string configPath = Path.Combine(
                Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
                "PointExtractor.cfg");

            if (!File.Exists(configPath))
            {
                // Создаем файл с примером, если его нет
                File.WriteAllText(configPath, "DataXmlPath=C:\\path\\to\\your\\file.xml");
                return null;
            }

            // Читаем все строки конфигурации
            foreach (string line in File.ReadAllLines(configPath))
            {
                if (line.StartsWith("DataXmlPath="))
                {
                    return line.Substring("DataXmlPath=".Length).Trim();
                }
            }
            return null;
        }
        catch
        {
            return null;
        }
    }

    private static string FormatAsLispList(List<int> numbers)
    {
        StringBuilder sb = new StringBuilder("(");
        bool first = true;

        foreach (int num in numbers)
        {
            if (!first) sb.Append(" ");
            sb.Append(num);
            first = false;
        }
        sb.Append(")");

        return sb.ToString();
    }

    public static List<int> GetPointIdsFromFile(string filePath)
    {
        List<int> ids = new List<int>();
        const string searchPattern = "<P id=\"";

        try
        {
            using (StreamReader reader = new StreamReader(filePath, Encoding.UTF8))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    int pos = 0;
                    while ((pos = line.IndexOf(searchPattern, pos, StringComparison.Ordinal)) != -1)
                    {
                        int start = pos + searchPattern.Length;
                        int end = line.IndexOf('"', start);

                        if (end > start)
                        {
                            string numStr = line.Substring(start, end - start);
                            if (int.TryParse(numStr, out int num))
                            {
                                ids.Add(num);
                            }
                        }

                        pos = end > 0 ? end : pos + 1;
                    }
                }
            }
            return ids;
        }
        catch (System.Exception ex)
        {
            throw new System.Exception($"Не удалось обработать файл {filePath}: {ex.Message}");
        }
    }
}
Просмотров: 318
 
Непрочитано 06.04.2025, 13:44
#2
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,406


Так объявляй не команду, а lisp-функцию, и передавай ей аргументы нужные. Раз уж все на NET делать нет желания / возможности.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 06.04.2025, 14:03
#3
sathalex


 
Регистрация: 02.07.2014
Сообщений: 59


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Так объявляй не команду, а lisp-функцию, и передавай ей аргументы нужные. Раз уж все на NET делать нет желания / возможности.
Вот так реализовал, вроде работает, спасибо:

Код:
[Выделить все]
(setq ids (GetPointIds (getfiled "--< Выберите файл >--" (getvar "DWGPREFIX") "xml" 8)))
Код:
[Выделить все]
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.DatabaseServices;

public class PointIdExtractor
{
    [LispFunction("GetPointIds")]
    public static ResultBuffer GetPointIdsLisp(ResultBuffer args)
    {
        Document doc = Application.DocumentManager.MdiActiveDocument;
        Editor ed = doc.Editor;

        try
        {
            if (args == null || args.AsArray().Length == 0)
            {
                ed.WriteMessage("\nОшибка: Требуется аргумент - путь к файлу");
                return null;
            }

            string filePath = args.AsArray()[0].Value.ToString();

            if (string.IsNullOrEmpty(filePath))
            {
                ed.WriteMessage("\nОшибка: Путь к файлу не может быть пустым");
                return null;
            }

            if (!File.Exists(filePath))
            {
                ed.WriteMessage($"\nОшибка: Файл не найден по пути: {filePath}");
                return null;
            }

            List<int> ids = GetPointIdsFromFile(filePath);

            ResultBuffer result = new ResultBuffer();
            foreach (int id in ids)
            {
                result.Add(new TypedValue((int)LispDataType.Int32, id));
            }

            return result;
        }
        catch (System.Exception ex) // ← Исправлено здесь
        {
            ed.WriteMessage($"\nОшибка: {ex.Message}");
            return null;
        }
    }

    private static List<int> GetPointIdsFromFile(string filePath)
    {
        List<int> ids = new List<int>();
        const string searchPattern = "<P id=\"";

        try
        {
            using (StreamReader reader = new StreamReader(filePath, Encoding.UTF8))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    int pos = 0;
                    while ((pos = line.IndexOf(searchPattern, pos, StringComparison.Ordinal)) != -1)
                    {
                        int start = pos + searchPattern.Length;
                        int end = line.IndexOf('"', start);

                        if (end > start)
                        {
                            string numStr = line.Substring(start, end - start);
                            if (int.TryParse(numStr, out int num))
                            {
                                ids.Add(num);
                            }
                        }

                        pos = end > 0 ? end : pos + 1;
                    }
                }
            }
            return ids;
        }
        catch (System.Exception ex) // ← И здесь
        {
            throw new System.Exception($"Не удалось обработать файл {filePath}: {ex.Message}");
        }
    }
}
sathalex вне форума  
 
Непрочитано 06.04.2025, 14:14
#4
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,406


Мелкий вопрос - [де]сериализация не катит? Обязательно вручную читать файл?
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 06.04.2025, 14:52
#5
sathalex


 
Регистрация: 02.07.2014
Сообщений: 59


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Мелкий вопрос - [де]сериализация не катит? Обязательно вручную читать файл?
Я не знаю, что такое [де]сериализация. Почитаю позже за это.
sathalex вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > .NET > C#. Передать для выполнения значение локальной переменной AutoCAD.



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как сохранить значение переменной _LUPREC на всех чертежах? Михаил777 AutoCAD 13 01.03.2017 00:00
VBA. Как вывести значение переменной формуле? Curiosity Программирование 3 16.09.2014 16:23
Можно ли заставить AutoCad выбрать максимальное значение из выделенного диапазона таблицы? RNB AutoCAD 2 15.09.2014 05:35
Excel VBA как задать в формуле значение ячейки переменной h5r32 Программирование 8 29.08.2014 12:03
autocad 2010 и как повторить введенное значение buzz113 AutoCAD 14 15.09.2011 09:16