Ứng Dụng Nâng Cao GUID và Shared Parameters Trong Revit API C#

/Bài viết

    Bài viết cuối cùng trong series về GUIDShared Parameters trong Revit API C#! Đến đây, bạn đã nắm vững cách:

    • Hiểu về vai trò của Shared Parameters và tầm quan trọng của GUID.
    • Đọc giá trị của Shared Parameters từ các Element bằng GUID.
    • Ghi và cập nhật giá trị cho Shared Parameters.
    • Quản lý (tạo nhóm, tạo thông số mới) trực tiếp trong file Shared Parameter (.txt).

    Giờ là lúc chúng ta tổng hợp lại kiến thức này và nhìn vào bức tranh lớn hơn: làm thế nào để áp dụng những khả năng này vào các trường hợp thực tế phức tạp, và những lưu ý quan trọng để đảm bảo code của bạn hoạt động ổn định và hiệu quả.

    Gắn Shared Parameters Vào Category/Element: Sử Dụng Binding

    Việc tạo một Shared Parameter trong file .txt chỉ là bước đầu tiên. Để parameter đó thực sự hiển thị và có thể được sử dụng trong một dự án hoặc Family, bạn cần "gắn" (bind) nó vào một hoặc nhiều Category (hạng mục) của Revit. Quá trình này được thực hiện thông qua các đối tượng Binding trong Revit API.

    Có hai loại Binding chính:

    • InstanceBinding: Parameter sẽ xuất hiện cho mỗi thể hiện (instance) của Element thuộc Category được gắn. Ví dụ: "Mã tài sản" của từng chiếc bàn.
    • TypeBinding: Parameter sẽ xuất hiện cho kiểu (type) của Element thuộc Category được gắn. Ví dụ: "Vật liệu khung" của tất cả các cửa sổ cùng loại.

    Để thực hiện binding, bạn cần truy cập BindingMap của tài liệu Revit:

    using Autodesk.Revit.DB;
    using Autodesk.Revit.UI;
    using System.Linq;
    
    // Giả sử 'doc' là đối tượng Document hiện tại
    // Giả sử 'newExternalDefinition' là một ExternalDefinition bạn đã tạo hoặc tìm thấy
    
    CategorySet categories = doc.Application.Create.NewCategorySet();
    
    // Thêm các Category mà bạn muốn gán Shared Parameter vào
    // Ví dụ: Gán cho tường (Walls) và cửa (Doors)
    categories.Insert(doc.Settings.Categories.get_Item(BuiltInCategory.OST_Walls));
    categories.Insert(doc.Settings.Categories.get_Item(BuiltInCategory.OST_Doors));
    
    // Tạo một InstanceBinding hoặc TypeBinding
    // InstanceBinding:
    InstanceBinding instanceBinding = doc.Application.Create.NewInstanceBinding(categories);
    
    // TypeBinding: (Nếu bạn muốn nó là Type Parameter)
    // TypeBinding typeBinding = doc.Application.Create.NewTypeBinding(categories);
    
    
    // Lấy BindingMap của Document
    BindingMap bindingMap = doc.ParameterBindings;
    
    using (Transaction tr = new Transaction(doc, "Gắn Shared Parameter vào Project"))
    {
        tr.Start();
    
        // Thêm binding vào BindingMap
        // Nếu parameter đã được gắn, phương thức này sẽ trả về false
        if (!bindingMap.Insert(newExternalDefinition, instanceBinding, BuiltInParameterGroup.PG_DATA))
        {
            // Có thể parameter đã tồn tại hoặc có lỗi
            // Kiểm tra xem nó có tồn tại rồi không
            if (bindingMap.Contains(newExternalDefinition))
            {
                TaskDialog.Show("Thông báo", $"Shared Parameter '{newExternalDefinition.Name}' đã được gắn vào dự án.");
            }
            else
            {
                TaskDialog.Show("Lỗi", $"Không thể gắn Shared Parameter '{newExternalDefinition.Name}' vào dự án.");
                tr.RollBack();
                return; // Thoát nếu lỗi
            }
        }
        else
        {
            TaskDialog.Show("Thành công", $"Đã gắn Shared Parameter '{newExternalDefinition.Name}' vào các Category đã chọn.");
        }
    
        tr.Commit();
    }
    

    Lưu ý:

    • BuiltInParameterGroup.PG_DATA: Chỉ định nhóm thông số mà Shared Parameter sẽ xuất hiện trong giao diện Revit (ví dụ: Data, Graphics, Identity Data...).
    • Bạn cần đảm bảo newExternalDefinition thực sự là một ExternalDefinition (tức là một Shared Parameter).

    Các Trường Hợp Sử Dụng Nâng Cao

    Kết hợp các kỹ thuật đã học, bạn có thể tạo ra nhiều công cụ Revit API mạnh mẽ:

    • Tạo Công Cụ Chuẩn Hóa Dữ Liệu Dự Án: Tự động tạo và gán một bộ Shared Parameters chuẩn cho tất cả các dự án mới, đảm bảo mọi thông tin cần thiết đều được thu thập và quản lý thống nhất.
    • Tự Động Điền Thông Tin Cấu Kiện: Đọc dữ liệu từ cơ sở dữ liệu ngoài (ví dụ: Excel, SQL Server) và tự động điền các thông số như mã sản phẩm, ngày sản xuất, nhà cung cấp vào các Element tương ứng trong Revit.
    • Đồng Bộ Hóa Dữ Liệu Hai Chiều: Phát triển Add-in cho phép người dùng xuất dữ liệu Shared Parameters ra một ứng dụng khác để chỉnh sửa, sau đó nhập lại vào Revit, đảm bảo GUID được sử dụng để nhận diện đúng thông số cần cập nhật.
    • Kiểm Tra và Đánh Giá Chất Lượng Dữ Liệu: Tự động quét các mô hình Revit để kiểm tra xem các Shared Parameters quan trọng có bị thiếu, có giá trị không hợp lệ, hoặc có sai định dạng hay không, sau đó báo cáo hoặc tự động sửa chữa.
    • Tạo Tham Số "Động" (Dynamic Parameters): Mặc dù Revit API không cho phép tạo "Dynamic Shared Parameters" theo nghĩa là chúng tự thay đổi giá trị mà không cần code, bạn có thể tạo các add-in chạy định kỳ hoặc theo sự kiện để tính toán và cập nhật giá trị của Shared Parameters dựa trên các yếu tố khác trong mô hình.

    Lưu Ý Quan Trọng Khi Làm Việc Với GUID & Shared Parameters

    Để đảm bảo các ứng dụng của bạn hoạt động hiệu quả, ổn định và không gây ra lỗi dữ liệu, hãy ghi nhớ những điểm sau:

    • Luôn luôn thực hiện các thay đổi đối với mô hình trong một Transaction và sử dụng khối using để đảm bảo Transaction được xử lý đúng cách, bất kể có lỗi hay không. using (Transaction tr = new Transaction(doc, "Tên giao dịch")) { tr.Start(); /* Code */ tr.Commit(); }
    • Xử Lý GUID Cẩn Thận:
      • Không tự ý thay đổi GUID của Shared Parameter đã tồn tại: Khi bạn tạo một Shared Parameter, GUID của nó là vĩnh viễn. Việc thay đổi GUID của một parameter đã được sử dụng có thể dẫn đến mất dữ liệu hoặc không thể truy cập được dữ liệu cũ.
      • Tạo GUID mới cho parameter mới: Luôn sử dụng Guid.NewGuid() khi định nghĩa một Shared Parameter thực sự mới để đảm bảo tính duy nhất.
      • Lưu trữ GUID một cách an toàn: Nếu bạn cần tham chiếu đến các Shared Parameters cụ thể trong code của mình, hãy lưu trữ GUID của chúng trong code (ví dụ: dưới dạng hằng số const string hoặc static readonly Guid) hoặc trong một tệp cấu hình. Đừng hardcode tên của Shared Parameter, vì tên có thể thay đổi nhưng GUID thì không.
    • Kiểm Tra Sự Tồn Tại và Khả Năng Ghi:
      • Trước khi cố gắng tạo một Group hoặc Shared Parameter mới, hãy kiểm tra xem chúng đã tồn tại chưa (sharedParametersFile.Groups.get_Item(groupName)).
      • Trước khi ghi giá trị vào một Parameter, luôn kiểm tra parameter.IsReadOnly.
      • Kiểm tra xem Shared Parameter có thực sự được gắn vào Element hoặc Category mà bạn đang làm việc hay không.
    • Đơn Vị Đo Lường (Units) Khi Làm Việc Với Giá Trị Số:
      • Revit API làm việc với đơn vị nội bộ (internal units). Đối với chiều dài, đơn vị nội bộ là feet. Đối với diện tích là feet vuông, và thể tích là feet khối.
      • Khi đọc hoặc ghi các giá trị số (đặc biệt là StorageType.Double), bạn thường sẽ cần chuyển đổi giữa đơn vị hiển thị của người dùng và đơn vị nội bộ của Revit. Sử dụng UnitUtils.ConvertFromInternalUnits()UnitUtils.ConvertToInternalUnits().
    • Hiệu Suất:
      • Hạn chế việc đọc/ghi file Shared Parameter (.txt) quá nhiều lần trong cùng một phiên làm việc, đặc biệt trong các vòng lặp lớn.
      • Nếu bạn đang cập nhật hàng ngàn Element, hãy cố gắng thực hiện tất cả các thay đổi trong một hoặc một vài Transaction lớn thay vì nhiều Transaction nhỏ để cải thiện hiệu suất.
    • Revit API có thể thay đổi qua các phiên bản. Luôn kiểm tra tài liệu API cho phiên bản Revit mà bạn đang phát triển để đảm bảo các phương thức và lớp bạn đang sử dụng vẫn còn hiệu lực.
    • Sử dụng các khối try-catch để bắt và xử lý các ngoại lệ (exception) một cách duyên dáng, cung cấp thông báo lỗi hữu ích cho người dùng.