返回列表 上一主題 發帖

[發問] 如何加資料

第二個問題先擱下不表
第三個問題是否指先把mystr注冊在dictionary的index,d(mystr),而該index的default資料為 = 0(即 d(mystr)=0), 再引以offset(,4)計數?還有dictionary照理說應該是幾D array?

感覺愈來愈近真相!
80 字節以內
不支持自定義 Discuz! 代碼

TOP

本帖最後由 Hsieh 於 2011-1-7 20:27 編輯

回復 20# FAlonso
首先我必須先佩服的求知態度
記得當初剛接觸陣列與dictionary物件時,也有著跟你相同的疑惑
但我就是不求甚解的個性,就把TRANSPOSE函數作為處理陣列問題的方法而已
今天遇到您提出疑問,那就讓我們一起來探討他的奧秘吧!
以下是我個人對陣列與dictionary的理解方式
提供您做參考
若有不是之處,還請各位前輩指正

1.Range("A1:A4")算不算是一個陣列?
是陣列,而且是二維陣列
以下列程式碼測試該陣列狀態
  1. Sub Ex()
  2. Dim j%, i%, Ar As Variant
  3. On Error Resume Next
  4. Ar = [A1:A4]
  5. Do Until j > 2  'j為計算轉置次數的變數
  6. MsgBox IIf(IsArray(Ar), "ar是陣列", "ar不是陣列") '是否為陣列
  7. i = 1
  8. Do Until Err.Number > 0
  9. i = i + 1
  10. k = UBound(Ar, i)
  11. Loop
  12. MsgBox "此陣列為" & i - 1 & "維陣列" & Chr(10) & "被轉置" & j & "次" '第一維上限(列數)
  13. Err.Clear
  14. Ar = Application.Transpose(Ar)
  15. j = j + 1
  16. Loop
  17. End Sub
複製代碼
2.為什麼打直的格子,一次transpose就可以,打橫的要兩次?
那是因為join的引數必須是一維陣列

3.d(mystr) = d(mystr) + A.Offset(, 4).Value這句是怎解釋,為什麼可以作累加的作用?
因為dictionary物件,你可以直接視為陣列,當中的mystr就是索引值(一般陣列會是數值,在此是除了陣列型態以外的任何資料型態),代表此物見某個元素的指定索引
d(mystr)就是d這個物件的mystr位置的那個元素
d(mystr) = d(mystr) + A.Offset(, 4).Value  
變數(新值)=變數(原值)+常數
就好比一個變數了,所以自然就能計算累加值
學海無涯_不恥下問

TOP

回復 19# Hsieh
那麼正確的維數其實是怎樣定義? 想來想去都想不通
在我的示範,Range("A1:A4")算不算是一個陣列?
為什麼打直的格子,一次transpose就可以,打橫的要兩次? 我試過打直的用兩次transpose,會有錯誤出現

還有
  1. d(mystr) = d(mystr) + A.Offset(, 4).Value
複製代碼
這句是怎解釋,為什麼可以作累加的作用
是否dictionary自動就是array,不需declare(即像普通的變數要作x()這樣的宣告))?

希望H大解答
80 字節以內
不支持自定義 Discuz! 代碼

TOP

回復 18# FAlonso
儲存格指定出來的範圍
不論是1列或多列
excel均將視為二維陣列
經過transpose函數轉置後才會得到正確的維數
所以當你的原陣列是以一維陣列儲存多個陣列成為多維陣列時
如
Dim Ay()
For i = 0 To 10
   ReDim Preserve Ay(i)
   Ay(i) = Array(i * 1, i * 2, i * 3, i * 4, i * 5)
Next
[A1].Resize(i, 5) = Application.Transpose(Application.Transpose(Ay))
Ay陣列元素是陣列
要以一次寫入就必須使用2次transpose
學海無涯_不恥下問

TOP

本帖最後由 FAlonso 於 2011-1-8 20:25 編輯

關於transpose問題....

例如excel有如下排列
    A    B    C    D
1  r
2  e
3  s
4  t

將一個column的字連串:
transpose一次

結果是r,e,s,t
  1. Sub abc()
  2. Dim mystring
  3. mystring = Join(Application.Transpose(Range("A1:a4").Value), ",")  '注意這裡是一個column串

  4. Range("A10").Value = mystring

  5. End Sub
複製代碼
將一個row的字連串:
transpose二次

  A    B    C    D
1  r   t    u    i
  1. Sub abc()
  2. Dim mystring
  3. mystring = Join(Application.Transpose(Application.Transpose(Range("A1:D1"))), ",") '注意這裡是一個row串

  4. Range("A10").Value = mystring

  5. End Sub
複製代碼
結果是r,t,u,i

今日做了一點詳細研究,是土法大鍊鋼
先把以下程式抄進VBA
  1. Sub check()
  2. Dim ar As Variant
  3. Dim i As Integer

  4. Set ar = [a1:a4]   'try [a1:d1] later

  5. For i = 1 To 6
  6. ar = Application.Transpose(ar)
  7. Next

  8. Set ar = Nothing

  9. End Sub
複製代碼
打開檢視->區域變數視窗,再按F8,逐行執行,觀察ar陣的資料

先看[a1:a4],一個column的range
是一個2D陣列(看紅色圈子), variant(1 to 4,1 to 1)

transpose一次後,變成了一個1D陣列, variant(1 to 4),這個是可以進入join()程式的東東

不論再如何transpose,都只會重覆variant(1 to 4,1 to 1) -> variant(1 to 4) -> variant(1 to 4,1 to 1) 這個循環

再看[a1:d1](自己把程式修改),一個row的range
是一個2D陣列, variant(1 to 1,1 to 4),這裡不再print screen了,大家自己看看
transpose一次後,變成另外一個2D陣列,叫variant(1 to 4,1 to 1),這樣是不能進入join程式
transpose第二次,便變了variant(1 to 4),可以了!
但之後無論怎transpose,都只會重覆variant(1 to 4,1 to 1) -> variant(1 to 4) -> variant(1 to 4,1 to 1) 這個循環,永遠不會變回variant(1 to 1,1 to 4)這個設定

打個比喻,就等如一個2-D row的陣列,首先變了"類似"2-D column的形態,再變1-D array
而2-D column就馬上變了1-D array
這樣應該能夠解釋為什麼row要transpose多一次,但row為什麼要首先變成column形,不要問我

最後d1.items那行
看以下例子
  1. Dim myrange As Range
  2. Dim i As Integer, k
  3. Set myobject = CreateObject("scripting.dictionary")

  4. myobject("A") = Array(1, 2)
  5. myobject("B") = Array(4, 5)
  6. myobject("C") = Array(7, 8)

  7. Set myrange = Worksheets("sheet2").Range("A1").Resize(3, 2)

  8. k = myobject.items
  9. k = Application.Transpose(Application.Transpose(k))
  10. myrange = k
複製代碼
在完成myobject配置後,區域變數的顯示指該物件尚未是array(沒有那些variant(x,y),純粹是很散的架構)
把myobject.items叫出來,便看到k有variant(0,2)的1D形態(3個索引,"A","B","C")
打開k的"+"鍵,會看到k(0),k(1),k(2)各自都有variant(0,1)的1D形態(即每個索引中的兩個數字的表示)
transpose()一次,便會成一個variant(1 to 2,1 to 3)的2D陣列
其實此時已經可以貼上格子囉!試把resize(3,2)變成(2,3)看看!
不過因為我們想排成
      A       B
1    1       2
2    4       5
3   7        8
所以再transpose一次而已
80 字節以內
不支持自定義 Discuz! 代碼

TOP

回復  basarasy
這是很直觀的代碼
Hsieh 發表於 2011-1-3 22:50


兩次使用application.transpose有點難解,數學上應該沒轉變,所謂的"標準二維陣列"是什麼
80 字節以內
不支持自定義 Discuz! 代碼

TOP

回復 15# linshin1999

變數要用Object嗎?
Dim d as Object ??
50 字節以內
不支持自定義 Discuz! 代碼

TOP

在VBE模式下有一個?號,就是在寫VBA有問是題時可以點一下問號,然後把不懂的打進去搜尋,通長都會得到答案.
如下就是 Scripting.Dictionary 搜尋出來的結果,


Dictionary 物件與 PERL 相關陣列一樣。可以存放任何型式的資料項目陣列。每個項目都是唯一的關鍵字。該關鍵字用來取出單個項目,通常是整數或字串,可以是存放除陣列以外的任何型別資料。

下面舉例說明了如何建立一個 Dictionary 物件:

Dim d                        '建立一個變數
Set d = CreateObject(Scripting.Dictionary)
d.Add "a", "Athens"     '加入一些關鍵字和項目
d.Add "b", "Belgrade"
d.Add "c", "Cairo"
...

因為說明檔是直接翻譯的所以文句很不順,以上文字有經過修改,但是目前說明檔仍然是學習Excel最簡便的工具,大家做參考.
V98

TOP

還有1個小問題想請教Hsieh大大的.
可否用 Range(cells(,),cells(,)) 同時Select  2個or多個地方?
Range(cells(a,b),cells(c,d)) + Range(cells(e,f),cells(g,h))
50 字節以內
不支持自定義 Discuz! 代碼

TOP

回復 10# FAlonso
  1. Sub Ex()
  2. On Error Resume Next
  3. Dim Mystr(), MyCnt()
  4. i = 1
  5. Do Until Cells(i, 1) = ""
  6.    If IsError(Application.Match(Cells(i, 1) & "," & Cells(i, 2) & "," & Cells(i, 3) & "," & Cells(i, 4), Mystr, 0)) Then
  7.       ReDim Preserve Mystr(s)
  8.       ReDim Preserve MyCnt(s)
  9.       Mystr(s) = Cells(i, 1) & "," & Cells(i, 2) & "," & Cells(i, 3) & "," & Cells(i, 4)
  10.       MyCnt(s) = Cells(i, 5)
  11.       s = s + 1
  12.       Else
  13.       k = Application.Match(Cells(i, 1) & "," & Cells(i, 2) & "," & Cells(i, 3) & "," & Cells(i, 4), Mystr, 0)
  14.       MyCnt(k) = MyCnt(k - 1) + Cells(i, 5)
  15.     End If
  16.     i = i + 1
  17. Loop
  18. For i = 0 To s - 1
  19.    Cells(i + 1, 8).Resize(, 4) = Split(Mystr(i), ",")
  20.    Cells(i + 1, 12) = MyCnt(i)
  21. Next
  22. End Sub
複製代碼
學海無涯_不恥下問

TOP

        靜思自在 : 【停滯不前,終無所得】人都迷於尋找奇蹟,因而停滯不前;縱使時間再多、路再長,也了無用處,終無所得。
返回列表 上一主題