简体   繁体   English

VBA Excel-有没有办法只复制月份(A列)相等的行(例如1月),然后将其粘贴到另一张纸上?

[英]VBA Excel - is there a way to only copy rows where the months (column A) equal, for example, January and then paste that to another sheet?

Iv'e been breaking my head over this. 我为此一直在挣扎。

My first sheet contains these buttons: 我的第一张纸包含以下按钮:

ImageButtons 图像按钮

With this being the transportFile: 以此为transportFile:

transportFile transportFile

So I'm trying to make it so that just the rows that contain (in this case) January and february dates get pasted to the "2016" sheet. 因此,我试图做到这一点,以便仅将包含(在这种情况下)一月和二月日期的行粘贴到“ 2016”工作表中。

This is the code that I'm using right now: 这是我现在正在使用的代码:

If CheckBoxJanuary.Value = True Then
Worksheets("2016").Range(Worksheets("2016").Cells(2, 1), Worksheets("2016").Cells(janCount, 13)).Value = Worksheets("transportFile").Range(Worksheets("transportFile").Cells(2, 1), Worksheets("transportFile").Cells(janCount, 13)).Value
End If

If CheckBoxFebruary.Value = True Then
Worksheets("2016").Range(Worksheets("2016").Cells(janCount + 1, 1), Worksheets("2016").Cells(janCount + febCount, 13)).Value = Worksheets("transportFile").Range(Worksheets("transportFile").Cells(janCount + 1, 1), Worksheets("transportFile").Cells(janCount + febCount, 13)).Value
End If

"janCount" and "febrCount" represent the numbers of rows that contain January and february dates. “ janCount”和“ febrCount”表示包含一月和二月日期的行数。 This is being calculated in the transportFile with 这是在transportFile中使用

"=SUMPRODUCT(--(MONTH($A$2:$A$150)=1))" “ = SUMPRODUCT(-(MONTH($ A $ 2:$ A $ 150)= 1))”

and

"=SUMPRODUCT(--(MONTH($A$2:$A$1500)=2))" “ = SUMPRODUCT(-(MONTH($ A $ 2:$ A $ 1500)= 2))”

Afterwards, I run a loop that deletes the empty rows in the 2016 sheet. 然后,我运行一个循环,删除2016工作表中的空行。

Now I have 2 questions: 现在我有两个问题:

  1. In the sumproduct formula of January I had to reduce the range because excel counts every empty cell as a January one. 在一月份的sumproduct公式中,我不得不缩小范围,因为excel将每个空单元格都计为一月份。 It's almost October, so that's not a problem now. 快到十月了,所以现在不成问题了。 But in 2017, when there's no data yet, there will be 150 January dates. 但是在2017年,当没有数据时,将有150个1月日期。 How can I solve that? 我该如何解决?
  2. If someone (by mistake) puts a March in between the Februaries, my ranges get all messed up. 如果有人(由于错误)在2月之间插入了3月,则我的范围将全部混乱。 How can I avoid this? 如何避免这种情况?

If your column with dates is formatted properly as date, then why don't check for value of month(cell)? 如果您带有日期的列的格式正确地设置为日期,那么为什么不检查month(cell)的值呢?

You could do check for each combobox while looping through all cells in column A like 您可以在遍历A列中的所有单元格时检查每个组合框,例如

 If combo box "January" selected Then
      'month = 1 and non empty
      If (Month(Cells(i, 1).Value) = 1) And (Cells(i, 1) <> "") Then  
           'copy your rows to new sheet
      End if
 End if
 If combo box "Feb" selected Then
      'month = 2 and non empty
      ....

As for 1. " excel counts every empty cell as a January one" probably they can be excluded somehow, a crude way would be to do exact same sumproduct for all empty cells in a column and subtract them :) 至于1.“ excel将每个空单元格都计为一月一个”可能可以以某种方式排除它们,一种粗略的方法是对列中的所有空单元格进行完全相同的求和并减去它们:)

=SUMPRODUCT(--(MONTH($A$2:$A$150)=1))-SUMPRODUCT(--(($A$2:$A$150)=""))

EDIT 编辑

Ok I had to check the sumproduct, correct way is to use second array to check for cells that are non empty: 好了,我必须检查sumproduct,正确的方法是使用第二个数组检查非空的单元格:

=SUMPRODUCT(--(MONTH($A$2:$A$37)=1);--(($A$2:$A$37)<>"")) This will return count of cells that have month(cell)=1 AND cell.value <> empty so you don't get false count for January when empty cell returns month=1 =SUMPRODUCT(--(MONTH($A$2:$A$37)=1);--(($A$2:$A$37)<>""))这将返回具有month(cell)的单元格的计数= 1 AND cell.value <>为空,因此当空单元格返回month = 1时,您不会获得1月的错误计数

As for 2 if you would make the loop using VBA to go through all your data then it doesn't matter if they are in order or not as each cell month value will be read, irrespectively of order. 至于2,如果您要使用VBA遍历所有数据,那么它们是否有序无关紧要,因为每个单元月的值都将被读取,而与顺序无关。

EDIT 2 编辑2

I will not propose the solution for this option but maybe the Pivot table could be the good solution for that task? 我不会提出该选项的解决方案,但也许数据透视表可以解决该任务? VBA code could be use to modify displayed data in the pivot table depending on the selected checkboxes. 根据所选的复选框,可以使用VBA代码修改数据透视表中显示的数据。

This code will look at each checkbox on the sheet to decide which has been ticket (assuming the only checkboxes you have are for months and they're all named CheckBoxMMMMM ). 这段代码将查看工作表上的每个复选框,以决定哪些已出票(假设您只有几个月的复选框,并且都被命名为CheckBoxMMMMM )。

It then filters by those months and copies the filtered rows to the final sheet. 然后按那几个月过滤,并将过滤后的行复制到最终工作表中。

Sub CopyFiltered()

    Dim wrkSht As Worksheet
    Dim shp As Shape
    Dim FilterMonths As Collection
    Dim vItem As Variant
    Dim rLastCell As Range
    Dim rFilterRange As Range
    Dim vFilterString() As Variant
    Dim x As Long

    Set wrkSht = ThisWorkbook.Worksheets("TickBoxSheet")
    Set FilterMonths = New Collection

    'Get a collection of ticked dates.
    'This works by looking at each checkbox on the sheet.
    'It assumes they're all called 'CheckBoxMMMM' so it can build a real date from the name.
    For Each shp In wrkSht.Shapes
        If shp.Type = msoFormControl Then
            If shp.FormControlType = xlCheckBox Then
                If shp.ControlFormat.Value = 1 Then
                    FilterMonths.Add DateValue("1 " & Replace(shp.Name, "CheckBox", ""))
                End If
            End If
        End If
    Next shp

    'Create an array of "1 ,<date>,1 ,<2nd date>"
    x = 1
    ReDim vFilterString(1 To FilterMonths.Count * 2)
    For Each vItem In FilterMonths
        vFilterString(x) = 1
        vFilterString(x + 1) = Format(vItem, "m/d/yyyy")
        x = x + 2
    Next vItem

    'Apply the filter - the commented line works but is hardcoded.
    'The other filter line appears to be the same as the commented line, but isn't working....
    With ThisWorkbook.Worksheets("2016")
        If .AutoFilterMode Then .AutoFilterMode = False
        Set rLastCell = Sheet2.Cells.Find(What:="*", After:=.Cells(1, 1), SearchDirection:=xlPrevious)
        Set rFilterRange = .Range(.Cells(1, 1), rLastCell)
        rFilterRange.AutoFilter Field:=1, Operator:=xlFilterValues, Criteria2:=vFilterString

        'Copy the visible filtered cells to the transportfile sheet.
        .Range(.Cells(1, 1), rLastCell).SpecialCells(xlVisible).Copy Destination:=ThisWorkbook.Worksheets("transportfile").Range("A1")

    End With

End Sub

From what I can find on the internet the numerical value given to the array (1) returns all values in that month. 从网上可以找到的数值来看,给数组(1)的数值返回该月的所有值。 Other values available are: 其他可用值包括:

  • 0 year 0年
  • 1 month 1个月
  • 2 day 2天
  • 3 hour 3小时
  • 4 minute 4分钟
  • 5 second 5秒

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM