日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

VBA小模板,跨表统计的2种写法

發(fā)布時間:2024/3/13 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VBA小模板,跨表统计的2种写法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

問題和目標(biāo)

  • 問題: 是想統(tǒng)計一個excel 文件里,多個sheet里的內(nèi)容
  • 但是整個目標(biāo)可以細(xì)化為不同的分支需求
  • 有的統(tǒng)計需求是,每個表只單表統(tǒng)計,只是進行批量操作。比如例子里累加到每個sheet的指定位置:單元格D2
  • 有的需求是,多個表得某些行列累加等。比如例子里累加到,特定表“sheet1”的第6列
  • 造出來得文件

    ?

    ?2 實現(xiàn)方法1 (可能只適合VBA+EXCEL,不太干凈的寫法)

    2.1 基本思路

    • 雙層循環(huán)
    • 一層是循環(huán)各個sheet表
    • 一層是在某個sheet表內(nèi)取數(shù)據(jù),從頭取到尾(需要判斷下取第幾列,取到哪行為止)

    Sub t100() Dim sh1 As Object Set sh1 = ThisWorkbook.Worksheets("sheet1") sh1.Columns(6).Clear '重置輸出區(qū) sh1.Cells(1, 6) = "跨表sum"Dim j As ObjectFor Each j In ThisWorkbook.Worksheetsi = 2j.Cells(2, 4).Clear '重置輸出單元格,避免污染Do While j.Cells(i, 2) <> ""sh1.Cells(i, 6) = j.Cells(i, 2) + sh1.Cells(i, 6) '跨表對應(yīng)行累加統(tǒng)計j.Cells(2, 4) = j.Cells(i, 2) + j.Cells(2, 4) '單表多行累加i = i + 1LoopNext End Sub

    2.2 用EXCEL表的單元格,當(dāng)變量來存儲數(shù)據(jù)

    (其實我反思,EXCEL只應(yīng)用來顯示可能更好)

    • 如果是累加一個sheet的數(shù)據(jù),存在一個變量/1個單元格就行
    • 如果是累加多個sheet的數(shù)據(jù),需要存在多個excel單元格/ 1行/1列等

    2.3 重點1

    • 方法1直接把 j當(dāng)作了worksheets對象


    ? ? Dim j As Object
    ? ? For Each j In ThisWorkbook.Worksheets

    2.4?方法1,需要重置輸出區(qū)

    • 為什么呢?
    • 因為EXCEL不是變量,數(shù)組,是文件,是可以保存數(shù)據(jù)的
    • 不像 程序里的變量,數(shù)組,程序開始運行,創(chuàng)建--生---------程序運行結(jié)束,銷毀--滅,
    • 所以有可能上次運行的數(shù)據(jù)( 可以叫臟數(shù)據(jù)吧)還存著,會和新運行的結(jié)果累積起來
    • 所以就需要 先把EXCEL的輸出區(qū)域重置才行

    總結(jié):需要重置輸出區(qū)的2個原因

    • 第1:其實無論哪個方法,因為EXCEL作為一個數(shù)據(jù)文件,本身輸出區(qū)可能(只是可能,不是必然)是已經(jīng)被其他數(shù)據(jù)污染過的,所以進行整列/或整個區(qū)域的 輸出區(qū)清理是很有必要的。

    (比如你這次輸出200行數(shù)據(jù),下次只輸出150行數(shù)據(jù),那么上次的151-200行數(shù)據(jù)就可能污染第2次的結(jié)果,看起來像是第2次輸出的)

    • 第2,第1種方法的關(guān)鍵問題在于這:累加統(tǒng)計時,是以當(dāng)前EXCEL的單元格的現(xiàn)有值為基礎(chǔ)的,所以不清除老的數(shù)據(jù),必然出錯。

    • 而第2種方法,因為累計統(tǒng)計? a=a+ add的時候,是用的變量a ,變量每次即生即滅,是不會存在,EXCEL這種,事先就存在數(shù)據(jù)的問題的

    2.5? 方法1得歷史改進過程,沒什么用,有興趣得看看

    Sub t1() Dim sh1 As Object Set sh1 = ThisWorkbook.Worksheets("sheet1") Dim j As ObjectFor Each j In ThisWorkbook.WorksheetsFor i = 2 To 99 '寫死99這種這個很不好,需要線判斷最大行數(shù)sh1.Cells(i, 6) = j.Cells(i, 2) + sh1.Cells(i, 6)NextNext End SubSub t11() Dim sh1 As Object Set sh1 = ThisWorkbook.Worksheets("sheet1") Dim j As ObjectFor Each j In ThisWorkbook.Worksheetsi = 2Do While j.Cells(i, 2) <> ""sh1.Cells(i, 6) = j.Cells(i, 2) + sh1.Cells(i, 6)i = i + 1LoopNext End SubSub t12() Dim j As ObjectFor Each j In ThisWorkbook.Worksheetsi = 2Do While j.Cells(i, 2) <> ""j.Cells(2, 4) = j.Cells(i, 2) + j.Cells(2, 4)i = i + 1LoopNext End Sub

    3? 方法2: 運算和存儲都在程序的變量里進行,EXCEL只存儲和顯示最終結(jié)果

    (不過也有可能有問題,就是老數(shù)據(jù)的行數(shù)比新的多,導(dǎo)致這樣還是有臟數(shù)據(jù),嘿嘿)

    3.1 代碼寫法思路和方法1完全不同

    • 運算和存儲都在程序的變量里進行,EXCEL只存儲和顯示最終結(jié)果
    • VBA 和像方法1那么干,還是因為是內(nèi)置在EXCEL里的吧
    • 一般程序還是都把過程放在程序內(nèi)解決,
    • EXCEL表只是存儲最終結(jié)果? & 顯示出來

    Sub t200()'核心差異 '方法2,把j定義為 sheet的序號,而b作為worksheets對象,Set b = Worksheets(j)' '對應(yīng)方法1,直接把j當(dāng)作了worksheets對象'方法1,需要重置輸出區(qū) '方法2,因為都是用變量中轉(zhuǎn)的,單數(shù)據(jù)存1個變量里,多數(shù)據(jù)存在數(shù)組,因為變量做了重置,所以輸出區(qū)域就不做重置了Dim i, j, h Dim b As Object Dim sh1 As Object Set sh1 = ThisWorkbook.Worksheets("sheet1") Dim arr1()For j = 1 To ThisWorkbook.Worksheets.Counth = 0 '每個表分表統(tǒng)計i = 2 '每個表都從第2行開始,重置i行數(shù)'數(shù)組不需要重置?因為這個數(shù)組不需要循環(huán),就是要一次性累加'每次運行變量和數(shù)組都是消滅后重新生產(chǎn)的,不會像excel這種外部文件記錄了數(shù)據(jù)' 重置變量和數(shù)組是為了程序連續(xù)運行期間問題,就是為了,循環(huán),下次循環(huán)沖頭再來Set b = Worksheets(j)Do While b.Cells(i, 2) <> ""ReDim Preserve arr1(2 To i) '因為i在不同的表,無法確認(rèn)具體數(shù)值,有數(shù)據(jù)的行數(shù)都不同arr1(i) = b.Cells(i, 2) + arr1(i) '跨表對應(yīng)行累加統(tǒng)計,因為是多個數(shù)據(jù),需要用數(shù)組h = h + b.Cells(i, 2) '單表多行累加i = i + 1Loopb.Cells(2, 4) = h 'h本身做了重置,因此輸出單元格Cells(2, 4) 不需要再重置NextFor i = LBound(arr1) To UBound(arr1)sh1.Cells(i, 6) = arr1(i)NextEnd Sub

    3.2 定義sheet 不同

    • 方法2,把j定義為 sheet的序號,而b作為worksheets對象,Set b = Worksheets(j)'
    • 對應(yīng)方法1,直接把j當(dāng)作了worksheets對象

    3.3 不需要重置EXCEL的? 存儲+顯示區(qū)

    • 方法1,需要重置輸出區(qū)
    • 因為方法1,把那些區(qū)域又做顯示,又做存儲就有了需要重置清除的問題
    • '方法2,因為都是用變量中轉(zhuǎn)的,單數(shù)據(jù)存1個變量里,多數(shù)據(jù)存在數(shù)組,因為變量做了重置,所以輸出區(qū)域就不做重置了

    可以看到代碼里

    EXCEL輸出區(qū)域,只是從 代碼里取變量 或數(shù)組內(nèi)容進行顯示,和EXCEL本身區(qū)域的內(nèi)容沒關(guān)系,輸出后會直接覆蓋老數(shù)據(jù)

    (不過也有可能有問題,就是老數(shù)據(jù)的行數(shù)比新的多,導(dǎo)致這樣還是有臟數(shù)據(jù),嘿嘿)

    b.Cells(2, 4) = h ??

    ? ? For i = LBound(arr1) To UBound(arr1)
    ? ? ? ? sh1.Cells(i, 6) = arr1(i)
    ? ? Next


    3.4 代碼內(nèi)部的重置, 這個主要和循環(huán)有關(guān)系

    • 數(shù)組不需要重置?因為這個數(shù)組不需要循環(huán),就是要一次性累加
    • ?每次運行變量和數(shù)組都是消滅后重新生產(chǎn)的,不會像excel這種外部文件記錄了數(shù)據(jù)
    • ?重置變量和數(shù)組是為了程序連續(xù)運行期間問題,就是為了,循環(huán),下次循環(huán)重頭再來

    3.5 方法2的歷史代碼,沒啥用

    Sub t2() Dim i, j, h Dim b As ObjectFor j = 1 To ThisWorkbook.Worksheets.Counth = 0 '每個表分表統(tǒng)計i = 2 '每個表都從第2行開始,重置i行數(shù)Set b = Worksheets(j)Do While b.Cells(i, 2) <> ""h = h + b.Cells(i, 2)i = i + 1Loopb.Cells(2, 4) = hNextEnd SubSub t21() Dim i, j Dim b As Object Dim sh1 As Object Set sh1 = ThisWorkbook.Worksheets("sheet1")For j = 1 To ThisWorkbook.Worksheets.Counti = 2 '每個表都從第2行開始,重置i行數(shù)Set b = Worksheets(j)Do While b.Cells(i, 2) <> ""sh1.Cells(i, 6) = b.Cells(i, 2) + sh1.Cells(i, 6)i = i + 1LoopNextEnd Sub

    總結(jié)

    以上是生活随笔為你收集整理的VBA小模板,跨表统计的2种写法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。