[VBA] Zwcad. Otwórz i wczytaj dane z Excela.


Recommended Posts

Witam, chciałbym stworzyć procedurę w zwcadzie, która po uruchomieniu:

1. otworzy okienko windowsowe "Otwórz plik" z przefiltrowaniem tylko .*xlsx

2. Po wybraniu pliku prześledzi odpowiednie kolumny odpowiedzialne za koordynaty x, y, z w odpowiednim arkuszu excelowym i zacznie je zapisywać do jakiejś tablicy, bądź od razu weźmie się za wstawianie punktów w modelu.

 

O co chodzi?
Otóż mam tak zwany plik SAF (Strucural Analytical Format) (w załączniku przykładowy) - wygenerowany z programy Archicad - jest to plik z rozszerzeniem xlsx zawierający m.in.

- koordynaty węzłów -> w arkuszu "StructuralPointConnection"

- geometrię belek i słupów (linia łącząca 2 węzły) -> w arkuszu "StructuralCurveMember"

- geometrię ścian, płyt, powłok (obszar złożony z 4 węzłów) -> w arkuszu "StructuralSurfaceMember"

Poza tym zawiera więcej ciekawych informacji - jak materiał, przekrój ale w moim projekcie nieistotne.

 

Otóż docelowo chciałbym aby ZWCAD narysował w przestrzeni wszystkie występujące belki, słupy (jako linie) oraz ściany płyty i powłoki  jako powierzchnie 3d.

Pomożecie?

 

 

1112.xlsx

Link to comment
Share on other sites

OK, mamy szukanie pliku (coś nie działa filtr przy wybieraniu i nie wiem co to za "nFilterIndex" no ale jest. Usunąłem zbędną część.

Option Explicit

'----------------------------------------------------------------------

' 64 bit VBA 7 version of File and Folder Browswers

' FileBrowseOpen()
' FileBrowseSave()
' FolderBrowse()

' Much of the original 32 bit module was donated by the good people of XtremeVbTalk.com
' I massaged it to be 64 bit with VBA 7 code lifted from numerous sites on the web

'----------------------------------------------------------------------

Private Declare PtrSafe Function GetOpenFileName Lib "comdlg32.dll" Alias _
"GetOpenFileNameA" (pOpenfilename As OPENFILENAME) As Long

'(...)

Private Type OPENFILENAME
lStructSize As Long
hWndOwner As LongPtr
hInstance As LongPtr
lpstrFilter As String
lpstrCustomFilter As String
nMaxCustFilter As Long
nFilterIndex As Long
lpstrFile As String
nMaxFile As Long
lpstrFileTitle As String
nMaxFileTitle As Long
lpstrInitialDir As String
lpstrTitle As String
flags As Long
nFileOffset As Integer
nFileExtension As Integer
lpstrDefExt As String
lCustData As Long
lpfnHook As LongPtr
lpTemplateName As String
End Type

'(...)

Public Function FileBrowseOpen(ByVal sInitFolder As String, _
ByVal sTitle As String, _
ByVal sFilter As String, _
ByVal nFilterIndex As Integer) As String


Dim OpenFile As OPENFILENAME
Dim lReturn As Long

sInitFolder = CorrectPath(sInitFolder)


OpenFile.lpstrInitialDir = sInitFolder

' Swap filter separator for api separator
sFilter = Replace(sFilter, "|", Chr(0))



OpenFile.lpstrFilter = sFilter
OpenFile.nFilterIndex = nFilterIndex
OpenFile.lpstrTitle = sTitle


OpenFile.hWndOwner = 0
OpenFile.lpstrFile = String(257, 0)

OpenFile.nMaxFile = LenB(OpenFile.lpstrFile) - 1
OpenFile.lStructSize = LenB(OpenFile)

OpenFile.lpstrFileTitle = OpenFile.lpstrFile
OpenFile.nMaxFileTitle = OpenFile.nMaxFile

OpenFile.flags = 0

lReturn = GetOpenFileName(OpenFile)

If lReturn = 0 Then
FileBrowseOpen = ""
Else
FileBrowseOpen = Trim(Left(OpenFile.lpstrFile, InStr(1, OpenFile.lpstrFile, vbNullChar) - 1))
End If

End Function

'(...)

Private Function CorrectPath(ByVal sPath As String) As String
If Right$(sPath, 1) = "\" Then
If Len(sPath) > 3 Then sPath = Left$(sPath, Len(sPath) - 1) ' Strip backslash from non-root
Else
If Len(sPath) = 2 Then sPath = sPath & "\" ' Append backslash to root
End If
CorrectPath = sPath
End Function

'(...)

Sub import_SAF()
MsgBox "importuję SAF"
Call FileBrowseOpen("c:", "Otwórz plik SAF", "Pliki SAF (*.xlsx)", 1)
End Sub

 

Link to comment
Share on other sites

XLSX jest plikiem binarny, nie można go odczytać tekstowo, VBA nie ma wbudowanej metody otwierania plików xlsx, dlatego trzeba posiłkować się zewnętrznymi narzędziami, np Excelem.
I tu rodzi się problem, bo może pojawić się sytuacja gdzie ktoś ma Excela, ktoś inny OpenOffica, ktoś inny jeszcze innego offica. A nasz program może mieć w założeniach, że wymagamy żeby użytkownik miał Excela, albo możemy obsługiwać różne sytuacje typu różne aplikacje, różne ich wersje i w ogóle to tylko kłopot z tym VBA. 😉 Ale tak na serio, to jeśli założymy że mamy Excela to otwarcie pliku możemy zrobić tak jak opisane tutaj:

Jak otworzyć plik Excela w VBA

Inne wersje i aplikacje pozostawmy na później, a może nie będzie to potrzebne.

Link to comment
Share on other sites

Musimy włączyć bibliotekę Microsoft Excel z poziomu References w VBA for Applications oraz odpalony program Excel

References.png

Sub import_SAF()
MsgBox "importuję SAF"

Dim excelApp As Excel.Application
Dim wb As Excel.Workbook
Dim folder, Name, FileName As String
Dim ExcelWasNotRunning As Boolean

Set excelApp = Nothing
Set wb = Nothing

FileName = FileBrowseOpen("c:", "Otwórz plik SAF", "Pliki SAF (*.xlsx)", 1)

'' Make sure Excel application is running

On Error Resume Next
Set excelApp = GetObject(, "Excel.Application")
If Err.Number <> 0 Then ExcelWasNotRunning = True
Err.Clear    ' Clear Err object in case error occurred.

If ExcelWasNotRunning Then
    Set excelApp = CreateObject("Excel.Application")
    If excelApp Is Nothing Then
        MsgBox "Cannot start Excel Application!"
        Exit Sub
    Else
        excelApp.Application.Visible = True
    End If
End If
excelApp.Application.Visible = True
'' Make sure the Workbook is open
On Error GoTo 0
Dim w As Excel.Workbook
For Each w In excelApp.Workbooks
    If UCase(w.FullName) = UCase(FileName) Then
        Set wb = w
        Exit Sub
    End If
Next

On Error Resume Next
If wb Is Nothing Then
    Set wb = excelApp.Workbooks.Open(FileName, , False)
End If

If wb Is Nothing Then
    MsgBox "Cannot open file: " & vbCrLf & FileName
Else
    wb.Activate
End If

End Sub

Można będzie jeszcze pobawić się automatycznemu wymuszeniem otwarcia programu Excel oraz Application.Visible = False ale to nie jest teraz jakieś bardzo istotne.

Wczytujemy, teraz jak się dobrać do środka tego excela i wyświetlić dane z arkusza

Link to comment
Share on other sites

Będę ogarniał użycie tych komórek, ale podpowiedz co najlepiej z nimi robić?

Zapisywać w tablicy i w niej szukać, w kolekcji i w niej szukać, czy bezpośrednio z excela za każdym razem pętlić? 

A może inny sposób?

Link to comment
Share on other sites

Ja bym zrobił z tego model.
Czyli opakować do oddzielnych klas punkty, krzywe , powierzchnie
Wczytałbym plik do postaci kolekcji (elementy w kolekcji dostępne są przez nazwę, w tablicy musielibyśmy opracować mechanizm wyszukiwania)

Opierając się tylko na własnym przeczuciu zakładam, że otworzenie modelu raz i praca na nim, będzie działało szybciej niż praca bezpośrednio na pliku excelowym. Dodatkowo daje nam otwartość na ewentualną zmianę formatu źródłowego.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share