Trong kỷ nguyên số hóa ngành xây dựng, việc trích xuất dữ liệu từ mô hình kết cấu (ETABS, SAP2000) là nhu cầu cấp thiết. Đa số kỹ sư quen thuộc với việc dùng CSI API (OAPI) để liên kết Excel với ETABS. Tuy nhiên, API có nhược điểm lớn: chậm chạp với mô hình lớn và yêu cầu bản quyền (phải mở phần mềm ETABS lên).
Bài viết này sẽ giới thiệu một phương pháp “đường tắt” mạnh mẽ hơn: Đọc trực tiếp file văn bản .e2k bằng Excel VBA. Kỹ thuật này cho tốc độ xử lý nhanh gấp hàng chục lần và không cần cài đặt ETABS trên máy tính xử lý.
1. Bản Chất Của File E2K
Trước khi đi vào code, ta cần hiểu “mỏ dữ liệu” chúng ta sắp khai thác. File .e2k (hoặc .$et trong các phiên bản cũ) thực chất là một file văn bản thuần túy (Plain Text) chứa toàn bộ định nghĩa mô hình.
Cấu trúc của nó được chia thành các khối (blocks) bắt đầu bằng dấu $. Ví dụ:
$ STORIES
"Story1" 3.2 0 0
"Story2" 3.2 3.2 0
$ FRAME SECTIONS
"C40x60" "Concrete Rectangular" "C30/37" 0.4 0.6 ...
Tư duy giải thuật: Nhiệm vụ của chúng ta là viết một “Parser” (bộ phân tích cú pháp) để đọc file này từ trên xuống dưới, phát hiện các từ khóa (như $ STORIES) và nhặt các con số ra đưa vào Excel.
2. Chiến Lược & Logic Triển Khai
Để xử lý file text hỗn độn này, chúng ta chia bài toán thành 3 module chính:
- Module Đọc (Reader): Load toàn bộ nội dung file
.e2kvào bộ nhớ máy tính (RAM) để xử lý cho nhanh, thay vì đọc từng dòng từ ổ cứng. - Module Tìm Kiếm (Finder): Quét qua dữ liệu trong bộ nhớ để tìm vị trí các “Block” dữ liệu cần thiết (ví dụ: tìm tọa độ cột, tìm tiết diện).
- Module Trích Xuất (Extractor): Xử lý chuỗi ký tự (String manipulation) để tách các con số ra khỏi văn bản. Đây là phần khó nhất vì dữ liệu trong E2K cách nhau bằng khoảng trắng không đều.
3. Triển Khai Code VBA (Step-by-Step)
Dưới đây là các hàm cốt lõi (Core Functions) đã được tôi việt hóa và tối ưu.
Bước 1: Hàm Đọc File E2K Vào Bộ Nhớ (Collection)
Chúng ta sử dụng FileSystemObject để mở file và đổ từng dòng vào một Collection. Việc này giúp các bước sau truy xuất dữ liệu cực nhanh.
Function ReadE2K(filePath As String) As Collection
' Tạo Collection mới để chứa dữ liệu
Dim data As Collection
Set data = New Collection
' Sử dụng FileSystemObject để đọc file text
Dim fso As Object, textStream As Object
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(filePath) Then
Set textStream = fso.OpenTextFile(filePath, 1) ' 1 = Mode Read Only
' Đọc từng dòng cho đến hết file
Do While Not textStream.AtEndOfStream
data.Add textStream.ReadLine
Loop
textStream.Close
End If
Set ReadE2K = data
End Function
Bước 2: Bộ Công Cụ Phân Tích Chuỗi Ký Tự (Parsers)
Đây là trái tim của thuật toán. Dữ liệu trong E2K thường có dạng:
"Dầm D22" "Concrete" 0.22 0.5
Các giá trị cách nhau bởi dấu cách (space), nhưng số lượng dấu cách không cố định. Ta cần các hàm chuyên biệt để lấy đúng giá trị mong muốn.
Hàm lấy số thực (Double) tại vị trí bất kỳ:
Hàm này tự động bỏ qua các khoảng trắng thừa để lấy đúng con số thứ n trong dòng.
Function GetDecimal(line As String, numberIndex As Long) As Double
Dim parts() As String
parts = Split(line, " ") ' Cắt chuỗi bằng dấu cách
Dim i As Long, matchCount As Integer
' Duyệt qua các mảnh đã cắt
For i = LBound(parts) To UBound(parts)
If IsNumeric(parts(i)) Then ' Nếu mảnh này là số
matchCount = matchCount + 1
' Nếu đếm đúng đến vị trí cần lấy
If matchCount = numberIndex Then
GetDecimal = CDbl(parts(i))
Exit Function
End If
End If
Next i
GetDecimal = 0
End Function
Hàm lấy chuỗi trong ngoặc kép (Quoted String):
Dùng để lấy Tên dầm, Tên tầng (thường nằm trong dấu "").
Function GetQuotedString(line As String, quoteIndex As Long) As String
Dim parts() As String
parts = Split(line, """") ' Cắt chuỗi bằng dấu ngoặc kép "
Dim i As Long, matchCount As Integer
For i = LBound(parts) To UBound(parts)
' Bỏ qua các phần rỗng
If Len(Trim(parts(i))) > 0 Then
matchCount = matchCount + 1
' Chuỗi trong ngoặc kép thường nằm ở vị trí chẵn trong mảng split
If matchCount = quoteIndex * 2 Then
GetQuotedString = CStr(parts(i))
Exit Function
End If
End If
Next i
GetQuotedString = ""
End Function
Bước 3: Hàm Thực Thi Chính (Main Process)
Ví dụ dưới đây minh họa cách lấy dữ liệu Chiều cao tầng (Stories) và xuất ra Sheet Excel.
Sub ExtractStoryData(data As Collection)
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("StoryData")
ws.Cells.Clear
' Tạo tiêu đề cột
ws.Range("A1:B1").Value = Array("Tên Tầng", "Cao Độ")
Dim rowId As Long: rowId = 2
Dim i As Long, j As Long, line As String
' 1. QUÉT: Duyệt qua toàn bộ file trong bộ nhớ
For i = 1 To data.Count
' 2. TÌM: Nếu thấy từ khóa "$ STORIES"
If InStr(1, data(i), "$ STORIES", vbTextCompare) > 0 Then
' 3. TRÍCH XUẤT: Bắt đầu đọc các dòng ngay bên dưới
j = i + 1
' Lặp cho đến khi gặp dòng trống hoặc hết file
Do While j <= data.Count And data(j) <> ""
line = data(j)
' Dùng hàm Parser ở Bước 2 để nhặt dữ liệu
' Lấy tên tầng (Chuỗi trong ngoặc kép thứ 1)
ws.Cells(rowId, 1).Value = GetQuotedString(line, 1)
' Lấy chiều cao (Số thực thứ 1)
ws.Cells(rowId, 2).Value = GetDecimal(line, 1)
rowId = rowId + 1
j = j + 1
Loop
Exit For ' Tìm xong thì thoát vòng lặp ngay cho nhẹ máy
End If
Next i
End Sub
4. Tổng Hợp Code
Để chạy chương trình, bạn tạo một Sub chính Main_Run để gọi các module trên:
Sub Main_Extract_E2K()
Dim filePath As String
' Tự động tìm file .e2k trong cùng thư mục với file Excel này
filePath = ThisWorkbook.Path & "\Model.e2k"
' Bước 1: Đọc file vào RAM
Dim dataColl As Collection
Set dataColl = ReadE2K(filePath)
If dataColl.Count = 0 Then Exit Sub
' Bước 2: Gọi các hàm trích xuất từng phần
ExtractStoryData dataColl
' ExtractFrameSections dataColl (Bạn có thể viết thêm hàm này tương tự)
MsgBox "Hoàn thành trích xuất dữ liệu!", vbInformation
End Sub
5. Tại Sao Kỹ Sư Nên Dùng Cách Này?
| Đặc điểm | Dùng CSI API (Cách cũ) | Dùng Parser E2K (Cách này) |
|---|---|---|
| Tốc độ | Chậm (giao tiếp qua OLE) | Cực nhanh (Xử lý Text thuần) |
| Bản quyền | Cần License ETABS & Cài đặt | Không cần cài ETABS |
| Độ khó | Trung bình | Khó hơn (cần hiểu logic chuỗi) |
| Ứng dụng | Chạy Analysis, Design | Lấy dữ liệu đầu vào, QA/QC mô hình |
Kết luận
Việc đọc file E2K mở ra khả năng kiểm soát dữ liệu tuyệt đối cho kỹ sư kết cấu. Bạn có thể xây dựng các tool tự động check tiết diện, kiểm tra vật liệu, hoặc so sánh khối lượng giữa các phương án thiết kế chỉ trong vài giây mà không cần mở phần mềm ETABS nặng nề.
Hãy thử áp dụng logic này để trích xuất Tọa độ điểm (Points) hoặc Gán tải trọng (Loads) trong dự án tiếp theo của bạn!
Nguồn tham khảo logic lập trình: Nodes Automations