Đọc Shared Parameters qua GUID trong Revit API C#

/Bài viết

    Ở bài viết trước, chúng ta đã tìm hiểu về Shared Parameters và tầm quan trọng của GUID trong việc định danh duy nhất chúng. Bây giờ, đã đến lúc chúng ta "xắn tay áo" và bắt đầu viết code để khai thác thông tin từ những thông số mạnh mẽ này.

    Bạn đã biết rằng GUID là chìa khóa để nhận diện một Shared Parameter bất kể tên hiển thị của nó. Trong Revit API, việc truy cập một Shared Parameter cụ thể từ một Element (một bức tường, cửa, cột, v.v.) thông qua GUID là phương pháp đáng tin cậy và chính xác nhất.

    Tương tác với đối tượng Parameter

    Bạn có thể lấy tất cả các Parameter của một Element thông qua thuộc tính Element.Parameters (một ParameterSet) hoặc phương thức Element.GetParameters().

    // Giả sử 'element' là một đối tượng Element bạn đã chọn hoặc tìm thấy
    ICollection<Parameter> allParameters = element.GetParameters("Tên tham số bạn muốn"); // Hoặc dùng element.Parameters để lấy tất cả
    

    Trong đó, các Parameter có thể là:

    • BuiltInParameter: Các thông số được Revit định nghĩa sẵn (ví dụ: BuiltInParameter.ALL_MODEL_TYPE_NAME). Chúng có một BuiltInParameterGroup và không có GUID.
    • UserDefinedParameter: Bao gồm Project Parameters và Shared Parameters. Đây là những thông số do người dùng tạo.

    Lấy DefinitionGUID của Shared Parameter

    Mỗi Parameter đều có một Definition đi kèm. Definition mô tả các đặc tính của một thông số, như tên, kiểu dữ liệu (StorageType), và nhóm. Đối với Shared Parameters, Definition này có một vai trò đặc biệt:

    • Definition: Lớp cơ sở cho các định nghĩa thông số.
    • ExternalDefinition: Một lớp dẫn xuất từ Definition, được sử dụng chuyên biệt cho Shared Parameters. Chỉ khi một Parameter là Shared Parameter, Definition của nó mới có thể được ép kiểu sang ExternalDefinition.

    Chính từ ExternalDefinition này, chúng ta mới có thể truy cập được GUID của Shared Parameter.

    Các Bước Đọc Giá Trị Của Shared Parameter Dựa Trên GUID

    Để đọc giá trị của một Shared Parameter từ một Element bằng GUID, chúng ta sẽ thực hiện các bước sau:

    1. Xác định GUID của Shared Parameter mục tiêu: Đây là GUID của Shared Parameter mà bạn muốn đọc. Bạn có thể tìm thấy nó trong Shared Parameter File (.txt) hoặc đã biết từ trước.
    2. Lấy đối tượng Element: Bạn cần có đối tượng Element mà bạn muốn đọc thông số từ đó (ví dụ: một bức tường, một cửa, một đối tượng chung).
    3. Lặp qua tập hợp các Parameter của Element đó.
    4. Kiểm tra xem Parameter có phải là Shared Parameter không: Sử dụng thuộc tính Parameter.IsShared.
    5. Nếu là Shared Parameter, ép kiểu Parameter.Definition sang ExternalDefinition và lấy thuộc tính Id (là một Guid).
    6. So sánh GUID lấy được với GUID mục tiêu của bạn.
    7. Nếu GUID khớp, bạn đã tìm thấy đúng Shared Parameter và có thể đọc giá trị của nó dựa trên StorageType của parameter.

    Ví Dụ (C#): Đọc Shared Parameter Theo GUID

    Hãy cùng xem một đoạn code ví dụ minh họa các bước trên. Giả sử bạn muốn đọc một Shared Parameter có tên hiển thị là "Mã tài sản" và có GUID cụ thể.

    using Autodesk.Revit.ApplicationServices;
    using Autodesk.Revit.Attributes;
    using Autodesk.Revit.DB;
    using Autodesk.Revit.UI;
    using Autodesk.Revit.UI.Selection;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    [Transaction(TransactionMode.Manual)]
    public class ReadSharedParameterByGuid : IExternalCommand
    {
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication uiApp = commandData.Application;
            UIDocument uiDoc = uiApp.ActiveUIDocument;
            Document doc = uiDoc.Document;
    
            // 1. Xác định GUID của Shared Parameter mục tiêu
            // Thay thế bằng GUID thực tế của Shared Parameter của bạn
            Guid targetGuid = new Guid("a1b2c3d4-e5f6-7890-1234-567890abcdef");
            string parameterName = "Mã tài sản"; // Tên gợi nhớ, không bắt buộc phải khớp với tên trong file .txt
    
            try
            {
                // Chọn một đối tượng trong Revit UI
                Reference pickedRef = uiDoc.Selection.PickObject(ObjectType.Element, "Vui lòng chọn một đối tượng để đọc thông số.");
                Element selectedElement = doc.GetElement(pickedRef);
    
                if (selectedElement == null)
                {
                    message = "Không có đối tượng nào được chọn.";
                    return Result.Cancelled;
                }
    
                // 2. Lấy tất cả Parameter của Element đã chọn
                Parameter desiredParameter = null;
                foreach (Parameter p in selectedElement.Parameters)
                {
                    // 3. Kiểm tra xem Parameter có phải là Shared Parameter không
                    if (p.IsShared)
                    {
                        // 4. Lấy Definition và ép kiểu sang ExternalDefinition
                        ExternalDefinition externalDef = p.Definition as ExternalDefinition;
    
                        if (externalDef != null)
                        {
                            // 5. Lấy GUID của Shared Parameter
                            Guid currentGuid = externalDef.Id;
    
                            // 6. So sánh GUID
                            if (currentGuid == targetGuid)
                            {
                                desiredParameter = p;
                                break; // Đã tìm thấy parameter mong muốn
                            }
                        }
                    }
                }
    
                // 7. Truy xuất giá trị nếu tìm thấy
                if (desiredParameter != null)
                {
                    string paramValue = string.Empty;
    
                    // Xử lý các kiểu dữ liệu khác nhau
                    switch (desiredParameter.StorageType)
                    {
                        case StorageType.Double:
                            paramValue = desiredParameter.AsDouble().ToString();
                            break;
                        case StorageType.ElementId:
                            ElementId elemId = desiredParameter.AsElementId();
                            if (elemId != ElementId.InvalidElementId)
                            {
                                Element linkedElem = doc.GetElement(elemId);
                                paramValue = linkedElem != null ? linkedElem.Name : "N/A";
                            }
                            else
                            {
                                paramValue = "Không có liên kết";
                            }
                            break;
                        case StorageType.Integer:
                            paramValue = desiredParameter.AsInteger().ToString();
                            break;
                        case StorageType.String:
                            paramValue = desiredParameter.AsString();
                            break;
                        case StorageType.None:
                            paramValue = "Kiểu dữ liệu không xác định";
                            break;
                    }
    
                    TaskDialog.Show("Thông tin Shared Parameter",
                                    $"Đối tượng: {selectedElement.Name}\n" +
                                    $"Tên Parameter: {desiredParameter.Definition.Name}\n" +
                                    $"GUID: {targetGuid}\n" +
                                    $"Giá trị: {paramValue}");
                }
                else
                {
                    TaskDialog.Show("Thông báo", $"Không tìm thấy Shared Parameter '{parameterName}' với GUID '{targetGuid}' trên đối tượng đã chọn.");
                }
    
                return Result.Succeeded;
            }
            catch (OperationCanceledException)
            {
                message = "Người dùng đã hủy thao tác chọn.";
                return Result.Cancelled;
            }
            catch (Exception ex)
            {
                message = "Lỗi: " + ex.Message;
                return Result.Failed;
            }
        }
    }
    
    • Chúng ta khởi tạo một Guid (targetGuid) là GUID của Shared Parameter mà bạn muốn tìm. Bạn phải thay đổi a1b2c3d4-e5f6-7890-1234-567890abcdef bằng GUID thực tế của Shared Parameter của bạn.
    • Người dùng được yêu cầu chọn một Element trong mô hình.
    • Code sẽ duyệt qua tất cả các Parameter của Element đó.
    • Với mỗi Parameter, chúng ta kiểm tra xem nó có phải là Shared Parameter hay không bằng p.IsShared.
    • Nếu là Shared Parameter, chúng ta ép kiểu p.Definition sang ExternalDefinition.
    • Từ ExternalDefinition, chúng ta lấy Id (chính là GUID của Shared Parameter đó) và so sánh với targetGuid của mình.
    • Khi tìm thấy đúng Shared Parameter, chúng ta đọc giá trị của nó. Lưu ý rằng Parameter.AsDouble(), Parameter.AsString(), v.v., được sử dụng tùy thuộc vào StorageType của parameter.