2012-11-21 41 views
0

我有一個帶有外部數據的舊VISIO文件。數據的源文件不再存在。 我試圖從visio複製和粘貼數據,以取得成功。如何將visio外部數據導出爲ex​​cel

然後我試圖通過VBA訪問數據,我不明白,結果我得到: (行的量是當期的,但該數據是時好時不)

Sub test() 
    Dim i, j As Integer 
    Dim r As Variant 
    Dim a() As Variant 
    Dim rowSTR As String 
    Dim vsoDataRecordset As Visio.DataRecordset 
    For i = 1 To Visio.ActiveDocument.DataRecordsets.Count 
     rowSTR = "" 
     a = Visio.ActiveDocument.DataRecordsets(i).GetRowData(1) 
     For j = 0 To UBound(a) - 1 
      rowSTR = rowSTR & vbTab & a(j) 
     Next j 
     Debug.Print i & ")" & rowSTR 
    Next i 
End Sub 

你知道如何從visio獲取這些數據以達到excel嗎?

感謝 阿薩夫

更新:增加了源和代碼輸出:我複查和不知道哪裏的數據來自... enter image description here

enter image description here

+0

你對數據的含義是否正確,有時不對?有時候數據有什麼不對? –

+0

添加了屏幕截圖 - 我相信我的代碼引用了錯誤的地方 - 只有偶數行纔有數據,它提醒了原創,但沒有更多。 –

回答

0

這個職位是舊的,但我遇到了同樣的問題,並有一個解決方案。在您的發佈代碼中,您引用了每個DataRecordSet並抓取第一行,而不是找到正確的並抓取所有行。

我們還必須避免使用i來計數從0到ExternalData.Count;行ID可以跳過數字,因此您必須使用正確的DataRecordset中的實際ID。

下面的代碼不完全漂亮,但它的工作原理。請注意,linked布爾值不是真正的數據集的一部分;但它等同於外部數據窗口中的「鏈」圖標。

這是爲Visio 2013編寫的,但我相信它也適用於其他版本。運行後,您可以使用%作爲分隔符將文件導入Excel。

Sub WriteDataSourceToFile() 

    ' REQUIRES: Microsoft Scripting Runtime (C:\Windows\SysWOW64\scrrun.dll) 

    ' Below we'll intentionally cause array length errors to test each Row 
    On Error Resume Next 

    ' Use this to put the drawing name in the first column of each row 
    Dim DrawingLabel As String 
    DrawingLabel = "DRAWING_NAME_HERE" 

    ' Used for getting the External Data from a specific window 
    Dim PagObj As Visio.Page 
    Dim vsoDataRecordset As Visio.DataRecordset 

    ' Used for grabbing all shapes with a link to the current Row 
    Dim shapeIDs() As Long 
    Dim testLong As Long 

    ' Currently only using the above as a test (linked or not linked) 
    Dim linked As Boolean 

    ' Stores all Row IDs from the DataRecordset and loops through each 
    Dim dataRowIDs() As Long 
    Dim dataRowID As Variant 

    ' Stores the actual Row information and appends to rowSTR for the delimited line 
    Dim rowData() As Variant 
    Dim rowDataInt As Integer 
    Dim rowSTR As String 

    ' Used for text file output 
    Dim fso As FileSystemObject 
    Set fso = New FileSystemObject 

    ' Create a TextStream and point it at a unique filename (based on the active document) 
    Dim stream As TextStream 
    Set stream = fso.CreateTextFile("C:\Users\Public\Documents\GEN_" & ActiveDocument.Name & ".txt", True) 

    ' Look through each window and find External Data (matches 2044) 
    For Each win In Visio.ActiveWindow.Windows 
     If win.ID = 2044 Then 
      Set vsoDataRecordset = win.SelectedDataRecordset 
      Exit For 
     End If 
    Next win 

    ' Get each Row ID from the DataRecordSet 
    dataRowIDs = vsoDataRecordset.GetDataRowIDs("") 

    ' Use each Row ID as a reference 
    For Each dataRowID In dataRowIDs 
     linked = False 

     ' Look through all pages and attempt to get Shape IDs linked to the active Row 
     For Each PagObj In ActiveDocument.Pages 
      PagObj.GetShapesLinkedToDataRow vsoDataRecordset.ID, dataRowID, shapeIDs 

      ' Attempting to reference a 0-length array will throw an error here 
      testLong = UBound(shapeIDs) 
      If Err.Number Then 
       Err.Clear 
      Else 
       ' If it didn't throw an error referencing the array, there's at least one linked shape 
       linked = True 
       Exit For 
      End If 
     Next PagObj 

     ' Build the output 
     rowSTR = linked 

     ' Get the array of Row Data 
     rowData = vsoDataRecordset.GetRowData(dataRowID) 

     ' Go through each column and append the value to the output string 
     For rowDataInt = 0 To UBound(rowData) 
      ' Using % as a delimeter to prevent text with commas causing a separated column 
      rowSTR = rowSTR & "%" & rowData(rowDataInt) 
     Next rowDataInt 

     'Output the string to the file, putting the label at the beggining of the row 
     stream.WriteLine DrawingLabel & "%" & rowSTR 
    Next dataRowID 

    stream.Close 
End Sub