Board logo

標題: 資料剖析(TextToColumns)對象可以不是儲存格嗎? [打印本頁]

作者: chiata    時間: 2013-2-1 13:24     標題: 資料剖析(TextToColumns)對象可以不是儲存格嗎?

請教各位前輩
Selection.TextToColumns
其中Selection似乎一定要是range,那有辦法直接對陣列變數進行資料剖析嗎?

ex:dim A(3) as double
A(0)="1,2,3"
想不透過sheet把資料剖析成A(1)=2、A(2)=2、A(3)=3
有辦法這樣做嗎?

謝謝
作者: Hsieh    時間: 2013-2-1 14:45

回復 1# chiata

陣列並不需要剖析即可直接寫入儲存格內
若你的意思是要將包含特定分隔符號的一維陣列中的陣列元素分隔後變成二維陣列寫入儲存格
那麼必須利用迴圈,將原陣列每個元素使用Split方法分割後寫入
若分割後的二維陣列,其每一列的元素個數不同,則必須一列一列的寫入
若分割後的二維陣列,其每一列的元素個數相同,則可以一次的將整個二維陣列透過2次的Application.Transpose寫入
而Split方法後的陣列元素,其資料型態則一律為String(字串)
大致上的程序結構如下
For i=Lbound(a) to Ubound(a) '原陣列迴圈
   ar=Split(a(i),",")  '逗點分割陣列元素,產生新的一維陣列
   Cells(i+1,1).Resize(,Ubound(ar)+1)=ar  '將一維陣列寫入
Next
作者: chiata    時間: 2013-2-4 13:40

回復 2# Hsieh


謝謝H大,應該說我會輸入一筆資料,此資料可能有兩種形態,第一種是純數字;ex:1 or 5 ...,第二種是字串;ex:1,3,5,
如果資料是字串的話我就用把它分割後丟進陣列裡,原本我會把它丟入某個儲存格中,在使用資料剖析(TextToColumns)做分割後再讀進陣列中,
之後計算就直接用陣列,不會使用到儲存格。
現在使用Split就可以不用資料剖析跟儲存格達到相同效果了!謝謝。
作者: chiata    時間: 2013-2-5 13:37

回復 2# Hsieh

而Split方法後的陣列元素,其資料型態則一律為String(字串)


[attach]14139[/attach]

如上圖,似乎使用Split後bb還是字串型態而不是陣列?
且使用val也不法將其改成數字型態,要換一個變數才能用val改成數字型態。
雖然說字串也能做數學運算就是了。
作者: Hsieh    時間: 2013-2-5 15:56

回復 4# chiata

在2#回覆中已經說明SPLIT所得到的是字串型態的陣列
而陣列無法改變其資料型態,唯有以另一資料型態陣列儲存才可改變元素的資料型態
  1. Sub ex()
  2. Dim ar()
  3. a = "1,3,5,7,9"
  4. bb = Split(a, ",")
  5. ReDim ar(UBound(bb))
  6. For i = 0 To UBound(bb)
  7. ar(i) = CDbl(bb(i))
  8. MsgBox ar(i) & "  IS  " & TypeName(ar(i))
  9. Next
  10. End Sub
複製代碼

作者: chiata    時間: 2013-2-5 16:24

回復 5# Hsieh

謝謝,我理解了!
剛剛使用發現字串可以運算,但不能做<、=、>等判斷,只能要判斷時使用val或是像H大所說的存成另一個陣列來使用。
作者: GBKEE    時間: 2013-2-5 16:36

本帖最後由 GBKEE 於 2013-2-5 16:37 編輯

回復 6# chiata
使用發現字串可以運算,但不能做<、=、>等判斷
  1. Option Explicit
  2. Sub Ex()
  3.     Dim A As String, B As Variant
  4.     A = "A5"
  5.     B = "10"
  6. '    MsgBox A * B   '** VBA 傳回: 錯誤值13  "型態不符合"
  7.     If IsNumeric(A) And IsNumeric(B) Then MsgBox A * B Else MsgBox "型態不符合"
  8.     A = "5"
  9.     B = "10"
  10.     If IsNumeric(A) And IsNumeric(B) Then MsgBox A * B Else MsgBox "型態不符合"
  11.     A = "1,2,3,4,5,6,7,8,9,10"
  12.     B = Split(A, ",")
  13.     MsgBox B(0) * B(UBound(B))
  14.     MsgBox B(0) < B(UBound(B))  '1 < 10 =True
  15.     MsgBox B(0) > B(UBound(B))  '1 > 10 =False
  16.     MsgBox B(0) = B(UBound(B))  '1 = 10 =False  
  17.     A = "1,2,3,4,5,6,7,8,9,A10"
  18.     B = Split(A, ",")
  19.     MsgBox B(0) * B(UBound(B))    '** VBA 傳回: 錯誤值13  "型態不符合"
  20. End Sub
複製代碼

作者: chiata    時間: 2013-2-8 14:10

回復 7# GBKEE
  1. Sub test()

  2.     For t = 1 To 110
  3.         If t <= "10" Then MsgBox t
  4.     Next t
  5.    
  6. End Sub
  7. Sub test2()

  8.     For t = 1 To 110
  9.         If t <= Val("10") Then MsgBox t
  10.     Next t
  11.    
  12. End Sub
複製代碼
小弟遇到的問題...test只有t=1跟10會跳msgbox出來,test2就t=1~10都會跳,不知道是哪邊出問題...
謝謝
作者: GBKEE    時間: 2013-2-9 15:24

回復 8# chiata
你沒有宣告 變數t的型態為數字,vba將視為 字串的對字串的比對
  1. Option Explicit         '強制需宣告變數
  2. Sub test()
  3.     Dim t As Integer
  4.     For t = 1 To 110
  5.         If t <= "15" Then MsgBox t
  6.     Next t   
  7. End Sub
  8. Sub test2()
  9.     Dim t As Variant  ' Variant 資料型態是所有沒被明確宣告為其他型態  **等同沒有宣告變數***
  10.     For t = 1 To 110
  11.         If t <= "10" Then MsgBox t & " <= 10"
  12.         If t <= "20" Then MsgBox t & " <= 20"
  13.         If t <= "30" Then MsgBox t & " <= 30"
  14.     Next t
  15. End Sub
複製代碼

作者: chiata    時間: 2013-2-9 16:23

回復 9# GBKEE


    [attach]14163[/attach]

謝謝G大,新年快樂,
圖中Variant/Integer不是代表此變數目前是Integer的狀態嗎?
我以為Variant是先埠指定變數型態,待程式執行後會自動判斷此變數合適型態,例如integer、string...等,使用上比較有彈性。
還是我觀念錯誤??
作者: GBKEE    時間: 2013-2-11 14:22

回復 10# chiata
  1. Sub test1()
  2.     Dim t As Integer
  3.     For t = 1 To 110
  4.         If t <= "9" Then MsgBox t & " <= 9"
  5.         If t <= "10" Then MsgBox t & " <= 10"
  6.     Next t
  7. End Sub
  8. Sub test2()
  9.     't 沒有明確宣告   
  10. For t = 1 To 110
  11.         If t > "30" Then MsgBox t & " > 30"         '當t<=9 為1位數 比對字串的第一位 "3"
  12.         If t <= "9" Then MsgBox t & " <= 9"        '當t<=9 為1位數 比對字串的第一位 "9"
  13.         If t <= "10" Then MsgBox t & " <= 10"   '當t<=9 為1位數 比對字串的第一位 "1"
  14.         MsgBox TypeName(t)
  15.     Next t
  16. End Sub
複製代碼

作者: kimbal    時間: 2013-2-16 17:07

回復  GBKEE
謝謝G大,新年快樂,
圖中Variant/Integer不是代表此變數目前是Integer的狀態嗎 ...
chiata 發表於 2013-2-9 16:23



t 是 variant/Integer 是對的.
但是當 在if 的時候
因為右方 "10" 是 文字, 不是數字,  if會把t轉為文字再對比 (VBA來看, " "裡的是文字)

例如t = 6
if 的時候
if (t<="10") then....
會變成
if ("6"<="10") then....
而不是
if (6<=10) then....

而文字"6" 第1個字 即 "6"  比 "10"的第1個字 "1" 大
換句話說 "6"<="10" 就是等於FALSE

TEST要這樣寫才可以得出效果
  1. Option Explicit         '強制需宣告變數
  2. Sub test()
  3.    Dim t As Integer
  4.    For t = 1 To 110
  5.        If t <= 15 Then MsgBox t
  6.    Next t
  7. End Sub

  8. Sub test2()
  9.     Dim t As Variant  
  10.     For t = 1 To 110
  11.        If t <= 15 Then MsgBox t & " <= 10"
  12.    Next t
  13. End Sub
複製代碼
不指明類型,是會比較方便些, 但是會增加像這樣的錯誤機會.
微軟近年來對Variant的方針也是變來變去.
作者: chiata    時間: 2013-2-18 15:37

例如t = 6
if 的時候
if (t<="10") then....
會變成
if ("6"<="10") then....
而不是
if (6<=10) then....
kimbal 發表於 2013-2-16 17:07


謝謝各位前輩,我暸解了!
但似乎一步一步執行程式,在If t <= 10跟If t <= "10"中t的型態都還是variant/Integer,可是實際上在If t <= "10"時VBA是用variant/String去判斷?
  1. Sub test()
  2.     Dim t As Variant
  3.     For t = 1 To 10
  4.         If t <= 10 Then MsgBox t & " <= 10"
  5.         If t <= "10" Then MsgBox t & " <= 10"
  6.     Next t
  7. End Sub
複製代碼





歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)