Excel VBA 重新格式化数据

Excel VBA Reformat Data

我有一些数据始终为 8 列 (A-H),每次行数可能不同(动态)。

如果A列中的字符串以: "IT", "LN" or "SJ" 那么G列的行值需要除以100.

如果字符串以“KK”结尾,则 G 列中的值需要为 除以 1000。

否则不需要对该行执行数学运算。

数据还需要先按 C 列字母顺序排序,然后再按 H 列排序。

完成后 header 行 (1)。可以删除。

到目前为止,我所拥有的“有效”,但它会在 G 列中产生一个非常长的 0.0000 值列表,这使得复制清理后的数据变得困难。

谁能告诉我更有效的解决方案?

 Sub Clean()

 Dim wkb As Workbook

 Set wkb = ActiveWorkbook

 Dim ws As Worksheet

Set ws = ActiveSheet


Range("A1").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
ws.Sort.SortFields.Clear
ws.Sort.SortFields.Add2 Key:=Range("H2:H2500" _
    ), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    
    
    
With ws.Sort
    .SetRange Range("A1:H2500")
    .Header = xlYes
    .MatchCase = False
    .Orientation = xlTopToBottom
    .SortMethod = xlPinYin
    .Apply
End With



Range("I2").Select
ActiveCell.FormulaR1C1 = _
    "=IF(OR(RIGHT(RC[-8],2) = ""SJ"", RIGHT(RC[-8],2) = ""LN"", RIGHT(RC[-8],2) = ""IT"", RIGHT(RC[-8],2) = ""KK""),IF(RIGHT(RC[-8],2) = ""KK"",RC[-2]/1000,RC[-2]/100),RC[-2])"
Range("I2").Select
Selection.Copy
Selection.End(xlToLeft).Select
Selection.End(xlDown).Select
Range("I2500").Select
Range(Selection, Selection.End(xlUp)).Select
Range("I3:I2500").Select
Range("I2500").Activate
ActiveSheet.Paste
Selection.End(xlUp).Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Range("G2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
    :=False, Transpose:=False
Selection.NumberFormat = "0.0000"

  Columns("I").Delete


 Dim strDataRange As Range
 Dim keyRange As Range

 Set strDataRange = Range("A:H")
 Set keyRange = Range("C1")
 strDataRange.Sort Key1:=keyRange, Header:=xlYes
 Rows(1).Delete

 End sub

示例输入数据

Codes Population Animal Type Size Housing Qty Average Cost Country
SHIB IT 4,504 DOGE Standard SMALL 15,019 9.5557 JP
CORG LN 33,052 DOGE Standard SMALL 8,816 31,404.9100 FR
SOG SJ 1,417 CAT Standard BIG 90 247.2508 ZM
CHOW KK 873 DOGE Standard BIG 9,192 177.2797 CN
FLOP AG 991 CAT Standard BIG 7 597.0650 BZ

所需的输出数据:

试试这个。它将所有内容复制到一个新的 sheet,这样您就不会丢失原始数据。如果您有大量数据,可以加快速度。

Sub x()

Dim ws As Worksheet, r As Long

Set ws = Worksheets.Add

Sheet1.Range("A1").CurrentRegion.Copy ws.Range("A1") 'assumes data on sheet1 (code name, change to suit)

For r = 2 To ws.Range("A" & Rows.Count).End(xlUp).Row
    Select Case Right(ws.Cells(r, 1), 2)
        Case "IT", "LN", "SJ": ws.Cells(r, "G").Value = ws.Cells(r, "G").Value / 100
        Case "KK": ws.Cells(r, "G").Value = ws.Cells(r, "G").Value / 1000
    End Select
Next r

With ws.Sort
    .SortFields.Clear
    .SortFields.Add2 Key:=ws.Range("C2:C" & ws.Range("A" & Rows.Count).End(xlUp).Row), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    .SortFields.Add2 Key:=Range("H2:H" & ws.Range("A" & Rows.Count).End(xlUp).Row), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    .SetRange Range("A1:H" & ws.Range("A" & Rows.Count).End(xlUp).Row)
    .Header = xlYes
    .MatchCase = False
    .Orientation = xlTopToBottom
    .SortMethod = xlPinYin
    .Apply
End With

End Sub

请尝试下一个简洁快速的代码。它会将要处理的范围放在一个数组中,并在最后下拉处理的结果。现在它 return 正在覆盖现有范围。它可以很容易地适应 return 在另一个 sheet:

Sub processRangeAH()
 Dim sh As Worksheet, lastR As Long, rng As Range, arr, i As Long
 
 Set sh = ActiveSheet
 lastR = sh.Range("A" & sh.rows.count).End(xlUp).row
 Set rng = sh.Range("A1:H" & lastR)
 rng.Sort Key1:=sh.Range("H1"), Order1:=xlAscending, Header:=xlYes
 arr = rng.Value2
 
 For i = 2 To UBound(arr)
    Select Case UCase(Right(arr(i, 1), 2))
        Case "IT", "LN", "SJ": arr(i, 7) = arr(i, 7) / 100
        Case "KK": arr(i, 7) = arr(i, 7) / 1000
    End Select
 Next i
 
 rng.Value2 = arr
 rng.Sort Key1:=sh.Range("C1"), Order1:=xlAscending, Header:=xlYes
 sh.Range("G2:G" & lastR).NumberFormat = "0.0000"
 sh.rows(1).Delete
End Sub

几个小时前我离开办公室时发布了这个答案,但不小心在另一个线程中...

只是为了看看如何使用数组,以提高更大范围的速度。