ExcelTip.Net留存知识帖 ---【注:附件之前被网盘供应商清空后,现已修复-现已修复-现已修复为本地下载!】
现在位置:首页 > 我的酷贴 > Excel VBA > 【VBA範例】:含有合併欄之Excel檔案如何排序

【VBA範例】:含有合併欄之Excel檔案如何排序

作者:绿色风 分类: 时间:2022-08-18 浏览:137
楼主
allall
【VBA範例】:含有合併欄之Excel檔案如何排序

Excel排序功能有限,一般檔案可以排序,含有合併欄位(merged cells)者則無法排序.

我拿Excel來儲存英文生字,檔案有四行(見圖),由左至右,第一行是生字,第二行英文字義,第三行中文字義,第四行例句.因一個字可能有數種不同字義,故第一行依字義數而合併.

添加生字時,我將之加到檔案末端,然後以下列程式排序.

排序原理:

一、在第一行增加兩行,原先之第一行如今成為第三行.
二、將第三行之合併欄取消,不再合併.如此有些欄位會還原成空白欄.
三、將第三行複製到第一行,空白欄則填以上方非空白欄中之字.以上圖為例:macabree有三列,malignant有兩列,mesmerize有兩列,morbid有三列,noctilucent有一列,則第一行將成為

macabre
macabre
macabre
malignant
malignant
mesmerize
mesmerize
morbid
morbid
morbid
noctilucent

四、將列數貼到第二行.
五、依第一、二行來排序.依第一行排序結果,是依字母順序排序,依第二行排序結果,是保持原先字義順序不變.
六、刪去第一及二行.排序已畢,不需要它們了.原來的第一行先變成第三行,如今又變回成第一行.
七、換到第二行去,第二行若是空欄,表示檔案到此為止.
八、查看第一行,若下一列是空白欄,表示它仍屬前一個字.一直查到下一列並非空白(表示是一個新字),則將上面數欄合併,並改換顏色.
九、一直重覆,直到第二行為空白才止.

========================================


  1. Option Explicit
  2. Sub sort_merged_cell()
  3. '
  4. '假設合併欄在第一行
  5. '程式原理:
  6. '一、在第一行插入兩行
  7. '二、取消第三行(原先之第一行)之合併欄
  8. '三、將第三行複製到第一行,若是空白欄,則使用上面的非空白欄之值.
  9. '四、將列數複製到第二行.
  10. '五、依第一、二行來排序.
  11. '六、刪去第一及二行.
  12. '七、將第一行合併並改換顏色.


  13.    Dim myText As String
  14.    Dim rng As Range
  15.    Dim cell As Range
  16.    Dim iCount As Integer
  17.    Dim iCount1 As Integer
  18.    Dim iCount2 As Integer
  19.    Dim i As Integer
  20.    Dim j As Integer
  21.    Dim k As Integer
  22.    
  23.    Cells(1, 5) = Minute(Now())
  24.    Cells(1, 6) = Second(Now())
  25.    Cells(1, 7) = Now()
  26.    
  27.    Application.DisplayAlerts = False
  28.    Application.ScreenUpdating = False
  29.    Application.Calculation = xlCalculationManual
  30.    myText = ""

  31. '尋找新加入的字
  32. '由下往上尋找非空白欄,然後檢視其顏色.新欄無顏色.
  33. '若已排序,則程式會將顏色定為19或44.
  34. '選最底欄
  35. Range("B65536").End(xlUp).Select
  36. k = ActiveCell.Row
  37. 'find the last cell whose cell pattern color is 19 or 44
  38. For i = 1 To 250 '最多找250列.不會一次加入那麼多列吧?
  39. If ActiveCell.Interior.ColorIndex <> 44 And ActiveCell.Interior.ColorIndex <> 19 Then

  40. j = ActiveCell.Row

  41. '若找到新欄,則繼續找


  42. If j > 1 Then
  43. Cells((j - 1), 2).Select
  44. End If
  45. Else '若找不到新欄,則跳出 for loop
  46. Exit For
  47. End If
  48. Next i
  49. '若找到新欄,則開始排序
  50. If i <> 1 Then
  51. '設定第二、三、四行之格式
  52. '第一行之格式由另一個程式 add_both_links設定
  53. Range(Cells(j, 2), Cells(k, 2)).Select
  54.        With Selection
  55.         .Font.Name = "Arial"
  56.         .Font.Size = 10
  57.         .WrapText = True
  58.         End With
  59.         
  60. Range(Cells(j, 3), Cells(k, 3)).Select
  61.     With Selection
  62.         .Font.Name = "細明體"
  63.         .Font.Size = 11
  64.         .WrapText = True
  65.     End With
  66.    
  67. Range(Cells(j, 4), Cells(k, 4)).Select
  68.        With Selection
  69.         .Font.Name = "Arial"
  70.         .Font.Size = 10
  71.         .WrapText = True
  72.         End With
  73. ' 插入兩行
  74.         
  75. Range(Cells(1, 1), Cells(k, 2)).Insert Shift:=xlToRight
  76.     Cells(2, 7) = Minute(Now())
  77.     Cells(2, 8) = Second(Now())
  78.     Cells(2, 9) = Now()
  79. '第三行是原先之第一行
  80. '取消第三行之合併欄
  81. '將第三行複製到第一行,若為空白欄,則填入最後一個非空白欄之值
  82. '將列數填到第二行

  83. Range(Cells(1, 3), Cells(k, 5)).MergeCells = False

  84.     Set rng = Range(Cells(1, 4), Cells(k, 4))
  85.         For Each cell In rng
  86.             If cell.offset(0, -1).Value <> "" Then
  87.                 myText = cell.offset(0, -1).Value
  88.             End If
  89.             cell.offset(0, -3).Value = myText
  90.             cell.offset(0, -2).Value = cell.Row
  91.         Next cell

  92.     Cells(3, 7) = Minute(Now())
  93.     Cells(3, 8) = Second(Now())
  94.     Cells(3, 9) = Now()
  95. ' 按第一、二行排序,然後將第一、二行刪除.

  96. Range(Cells(1, 1), Cells(k, 6)).Sort _
  97.         Key1:=Range("A1"), Order1:=xlAscending, _
  98.         Key2:=Range("B1"), Order2:=xlAscending, _
  99.         Header:=xlNo, OrderCustom:=1, _
  100.         MatchCase:=False, Orientation:=xlTopToBottom
  101.    
  102.     Cells(4, 7) = Minute(Now())
  103.     Cells(4, 8) = Second(Now())
  104.     Cells(4, 9) = Now()
  105. '設欄寬

  106. Cells(1, 1).ColumnWidth = 16
  107. Cells(1, 2).ColumnWidth = 66
  108. '刪去第一、二行
  109.    
  110.     Range(Cells(1, 1), Cells(k, 2)).Select
  111.     Selection.Delete Shift:=xlToLeft
  112. End If
  113.     iCount = 19
  114.       
  115.     Cells(5, 5) = Minute(Now())
  116.     Cells(5, 6) = Second(Now())
  117.     Cells(5, 7) = Now()
  118. ' 重新將同一字之各欄合併,並設顏色

  119. 'iCount: color index
  120. 'iCount1: beginning merge cell row #
  121. 'iCount2: ending merge cell row #
  122. Set rng = Range(Cells(1, 2), Cells(k, 2))
  123.     For Each cell In rng
  124.     If cell.offset(0, -1).Value <> "" Then
  125.     iCount1 = cell.Row
  126.     iCount2 = 0
  127.     Else
  128.     iCount2 = iCount2 + 1
  129.     End If
  130. '若第一行之下一欄非空格,表示是另外一字,該是設顏色及合併欄位的時候了.
  131.     If cell.offset(1, -1).Value <> "" Or cell.Row = k Then
  132.         Range(ActiveSheet.Cells(iCount1, 1), ActiveSheet.Cells(iCount1 + iCount2, 4)).Select
  133.         
  134.     If iCount = 19 Then
  135.    
  136.      With Selection.Interior
  137.         .ColorIndex = 19
  138.     End With
  139.      iCount = 44
  140.      
  141.      Else
  142.      
  143.      With Selection.Interior
  144.         .ColorIndex = 44
  145.     End With
  146.      iCount = 19
  147.          
  148.      End If
  149.               
  150.      Range(ActiveSheet.Cells(iCount1, 1), ActiveSheet.Cells(iCount1 + iCount2, 1)).Merge
  151.      
  152.     End If
  153.    
  154.     Next cell
  155. '設定欄邊

  156.     Range(Cells(1, 1), Cells(k, 4)).Select
  157.     With Selection.Borders(xlEdgeLeft)
  158.         .LineStyle = xlContinuous
  159.         .Weight = xlThin
  160.         .ColorIndex = xlAutomatic
  161.     End With
  162.     With Selection.Borders(xlEdgeTop)
  163.         .LineStyle = xlContinuous
  164.         .Weight = xlThin
  165.         .ColorIndex = xlAutomatic
  166.     End With
  167.     With Selection.Borders(xlEdgeBottom)
  168.         .LineStyle = xlContinuous
  169.         .Weight = xlThin
  170.         .ColorIndex = xlAutomatic
  171.     End With
  172.     With Selection.Borders(xlEdgeRight)
  173.         .LineStyle = xlContinuous
  174.         .Weight = xlThin
  175.         .ColorIndex = xlAutomatic
  176.     End With
  177.     With Selection.Borders(xlInsideVertical)
  178.         .LineStyle = xlContinuous
  179.         .Weight = xlThin
  180.         .ColorIndex = xlAutomatic
  181.     End With
  182.     With Selection.Borders(xlInsideHorizontal)
  183.         .LineStyle = xlContinuous
  184.         .Weight = xlThin
  185.         .ColorIndex = xlAutomatic
  186.     End With
  187.         
  188.     Cells(6, 5) = Minute(Now())
  189.     Cells(6, 6) = Second(Now())
  190.     Cells(6, 7) = Now()

  191. 'end_macro:
  192.    
  193.     Application.CutCopyMode = False
  194.     Application.ScreenUpdating = True
  195.     Application.DisplayAlerts = True
  196.     Application.Calculation = xlCalculationAutomatic

  197. End Sub
new.jpg
 
2楼
rongjun
还是少用合并单元格为好,否则处理数据会有所不便。
3楼
纵鹤擒龙水中月
学习了

免责声明

有感于原ExcelTip.Net留存知识的价值及部分知识具有的时间限定性因素, 经与ExcelTip.Net站长Apolloh商议并征得其同意, 现将原属ExcelTip.Net的知识帖采集资料于本站点进行展示, 供有需要的人士查询使用,也慰缅曾经的论坛时代。 所示各个帖子的原作者如对版权有异议, 可与本人沟通提出,或于本站点留言,我们会尽快处理。 在此,感谢ExcelTip.Net站长Apolloh的支持,感谢本站点所有人**绿色风(QQ:79664738)**的支持与奉献,特此鸣谢!
------本人网名**KevinChengCW(QQ:1210618015)**原ExcelTip.Net总版主之一

评论列表
sitemap