[REVIT API TASK] HƯỚNG DẪN TẠO ADD-IN sheet numbering (GÁN SỐ THỨ TỰ SHEET VÀO THAM BIẾN STT TỰ TẠO)
Bài viết này hướng dẫn cách lọc đối tượng từ tập hợp các đối tượng trong Revit, sao đó gán thuộc tính cho đối tượng vừa lọc.
Lưu ý là ở đây chúng ta không đi quá sâu về C# mà chỉ tập trung đến Revit API, mọi kiến thứ chuyên sâu bên C# trong bài viết nếu bạn đọc chưa rõ vui lòng để lại comment chúng tôi sẽ giải đáp. Và vì là những phần tương đối khó bạn đọc vui lòng đọc thật kĩ và làm theo từng thao tác.
BƯỚC 1: TẠO MỘT DỰ ÁN REVITAPI
Các bạn có thể tham khảo cách khởi tạo dự án tại đây: https://vietbimcoder.com/revitapifirststep/
BƯỚC 2: bắt đầu một thể hiện của class TRANSACTION có thể hiệu chỉnh các đối tượng trong revit
BƯỚC 3: tạo một thể hiện của clas Filteredelementcollector ĐỂ LẤY VÀ LỌC CÁC ĐỐI TƯỢNG
Linq là tập hợp các thuật toán để xử lý nhanh các mảng dữ liệu, bạn có thể tham khảo các sử dụng Linq tại đây: https://vietbimcoder.com/huong-dan-tao-add-in-filterselectionrebar/
Nếu mọi người đã hiểu rõ và quen với các thuật toán Revit, ta có thể viết gọn dòng lệnh như sau:
BƯỚC 4: Lặp qua mảng viewsheet và gán giá trị vào thuộc tính “STT” vào các đối tượng
Ở ví dụ này, chúng ta sẽ chỉ gán các ViewSheet thể hiện trong danh mục, tham biến này được Revit lưu trữ trong tham biến “Appears In Sheet List”.
Giá trị của tham biến này được lưu trự dưới dạng Yes/No (trong RevitAPI lưu trữ trong kiểu integer và chỉ có 2 giá trị 0 và 1).
Tạo thủ công tham biến “STT” để lưu trự số thứ tự:
Chúng ta tiếp tục viết các đoạn code sau:
BƯỚC 5: Commit transaction, thoát khỏi phương thức
BƯỚC 6: Build và test code
Các bạn có thể tham khảo cách hoàn tất một dự án tại đây: https://vietbimcoder.com/revitapifirststep/
Dưới đây là toàn bộ đoạn code của dự án Sheet Numbering
#region Namespaces using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using Autodesk.Revit.ApplicationServices; using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using Autodesk.Revit.UI.Selection; #endregion namespace SheetNumber { [Transaction(TransactionMode.Manual)] public class Command : IExternalCommand { public Result Execute(ExternalCommandData commandData,ref string message,ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; //1. Tạo một thể hiện của Transaction để có thể thay đổi các đối tượng trong mô hình Revit // "SheetNumber" ở đây sẽ được hiểu là một lệnh đã thực thi trong Revit, // Ctrl + Z sẽ Undo khối lệnh được tập hợp lại thành lệnh "SheetNumber" Transaction tx = new Transaction(doc, "SheetNumber"); //2. Bắt đầu Transaction tx.Start(); //3. Tạo một thể hiện của FilteredElementCollector chứa tất cả các đối tượng trong mô hình // ở đây, tham biến doc đại diện cho document đang được lọc. VD: 161205_F7_Beam_TS1.rvt FilteredElementCollector col = new FilteredElementCollector(doc); //4. Áp dụng bộ lọc lên tập hợp FilteredElemenetCollector // ở đây sử dụng bộ lọc OfClass(typeof(ViewSheet)) //để lấy ra tập hợp các ViewSheet (Sheet bản vẽ trong mô hình) col.OfClass(typeof(ViewSheet)); //5. Ép mảng dữ liệu từ class Element sang class ViewSheet bằng phương thức Cast<ViewSheet>() //để có thể sử dụng các thuộc tính và phương thức của class ViewSheet //6. Sử dụng namespace "using System.Linq;" và phương thức OrderBy(x => x.SheetNumber) //để sắp xếp lại tập hợp các ViewSheet dựa trên số hiệu bản vẽ (SheetNumber) //ở đây sử dụng phương thức OrderBy() để sắp xếp mảng từ thấp lên cao //7. Tạo thể hiện mảng ViewSheet và gán tập hợp đã lọc vào mảng vừa tạo List<ViewSheet> vss = new List<ViewSheet>(); vss = col.Cast<ViewSheet>().OrderBy(x => x.SheetNumber).ToList(); // Có thể viết gọn các dòng lệnh phía trên như sau: vss = new FilteredElementCollector(doc).OfClass(typeof(ViewSheet)).Cast<ViewSheet>().OrderBy(x => x.SheetNumber).ToList(); int i = 0; //8. Lặp qua các phần tử trong mảng ViewSheet foreach (ViewSheet vs in vss) { //9. Tạo thể hiện của class Parameter đại diện, phương thức LookupParameter() //tham biến "Appears In Sheet List" của đối tượng ViewSheet Parameter p1 = vs.LookupParameter("Appears In Sheet List"); //10. Lấy giá trị của tham biến bằng phương thức AsInteger() //kiểu Interger, chỉ có 2 giá trị 0 và 1 int i1 = p1.AsInteger(); //11. Kiểm tra biến i1 bằng 1 (checkbox được chọn) if (vs.LookupParameter("Appears In Sheet List").AsInteger() == 1) { //12. Gán giá trị vào tham biến "STT" // Lưu ý khi lấy tham biến "STT" từ đối tượng ViewSheet // ta nên để dòng lệnh trong cấu trúc try... catch // vì đây là tham biến tự tạo, nếu như vậy khi vô tình xóa mất // tham biến "STT" thì Revit sẽ không báo lỗi i++; try { Parameter p2 = vs.LookupParameter("STT"); //14. Tăng giá trị i và gán vào tham biến "STT" p2.Set(i); } catch (NullReferenceException ex) { //13. Báo lỗi, tham biến "STT" không tồn tại // Ở đây ta xài một class tự tạo để tự động thêm tham biến khi chưa tồn tại ParameterUtil.AddParameter(doc, "STT", AddParameterType.Instance, ParameterType.Integer, BuiltInParameterGroup.PG_IDENTITY_DATA, BuiltInCategory.OST_Sheets); Parameter p2 = vs.LookupParameter("STT"); //14. Tăng giá trị i và gán vào tham biến "STT" p2.Set(i); } } } //15. Kết thúc Transaction, Revit sẽ tự động cập nhập các thay đổi trong lệnh "SheetNumber" tx.Commit(); //16. Trả về Succeeded, thoát khỏi phương thức return Result.Succeeded; } } }
Hoàn tất mọi thứ, ta vào Revit test thử thôi: