2017-06-02 75 views
0

我需要一些关于我正在处理的特定宏的帮助。 宏处理已从pdf文件导入的数据列。导入过程会生成多张一致的数据,所有变量都保留在多张工作表的相同列中。该宏需要读取三列数字,将两列中的所有单元格从另一列中减去,将解算值置于每行末尾的空列中。然后重复两列的另一个组合。之后,它需要将解决的值与边距值进行比较,并生成一张新表格,该表格将失败的边距值所在的整行数据拖入工作簿前面的新工作表中。用于处理大量数据的excel的VBA中的宏

这是我到目前为止。 到目前为止,我可以在一张纸上预制此功能,但不知道如何将此功能自动转换为其他纸张。数字填充列B,C和D,答案应该放置在G,H和H为空之后的任何其他列中。

Private Sub FindAndCreateSheet3dBm() 
    ' Declare variables 
    Dim eWs As Worksheet 
    Dim rMargin As Range 
    Dim myUnion As Range    

     'Column G: subrtact max and measured values 
     Worksheets("page 6").Range("G1:G21").Formula = "=(C1-D1)" 
      '*need to fix sheet reference, make all sheets, add flexible range to 
      'end of G range 

     'Column H: subrtact measured and min values 
     Worksheets("page 6").Range("H1:H21").Formula = "=(D1-B1)" 
      '*need to fix sheet reference, make all sheets, add flexible range to 
      'end of H range  

     '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 
     ' Create the report sheet at first position then name it "Less than 3dBm" 
     Dim wsReport As Worksheet 
     Dim rCellwsReport As Range 
     Set wsReport = ThisWorkbook.Sheets.Add(Before:=ThisWorkbook.Sheets(1)) 
     wsReport.Name = "Less than 3dBm" 

     Set rCellwsReport = wsReport.Cells(1, 1) 

     'Create union of columns to search G and H? 
     Set myUnion = Union(Columns("G"), Columns("H")) 

     'Check whole Workbook, union G and H for values less than rMargin 

    NextSheet: 
     Next 
    End Sub 

谢谢

+0

我明白你的问题的方式是,你需要将第6页的那些行应用到所有其他页面?页面是指PDF中的工作簿还是页面? – ksauter

+0

你的理解是正确的。页面在Excel中的“工作表”中。每张表格都对应着从它来自的pdf页面,所以当我有一个40页的pdf时,我也有一个40页的excel工作簿。 –

回答

0

这应该为你的工作需要。在我进入我的代码之前,我只想指出,通常在询问'我该怎么做'这个问题时,你会从社区获得的回应是,SO不是我网站的代码。我们很乐意帮助修复损坏的代码,但这些问题通常可以通过Google解决。

这就是说,我想从我正在进行的项目中休息,所以我把它扔在一起。我希望在这里可以将它作为一个学习机会来学习如何编写更好的代码(也许在这个过程中得到老板的一些赞誉)。

下面的代码:

Private Sub FindAndCreateSheet3dBm() 
    ' Ideally, you wouldnt even use something like this. For your purposes 
    ' it will get you going. I highly recommend finding a dynamic way of 
    ' determining the positions of the data. It may be consistent now, but 
    ' in the world of programming, everything changes, especially when 
    ' you think it wont. 

    Const FIRST_INPUT_COL As Long = 3  ' Column C 
    Const SECOND_INPUT_COL As Long = 4  '   D 
    Const THIRD_INPUT_COL As Long = 2  '   B 

    Const FIRST_OUTPUT_COL As Long = 7  '   G 
    Const SECOND_OUTPUT_COL As Long = 8  '   H 

    Dim marginReport As Worksheet 
    Set marginReport = ThisWorkbook.Sheets.Add(Before:=ThisWorkbook.Sheets(1)) 
    marginReport.Name = "Less than 3dBm" 

    Dim targetWorksheet As Worksheet 

    For Each targetWorksheet In ThisWorkbook.Worksheets 
     If Not targetWorksheet Is marginReport Then 
      Dim inputData As Variant 
      inputData = targetWorksheet.UsedRange.value 

      Dim outputData As Variant 
      ' I resize the array to be the exact same as the first, but to add two additional columns 
      ReDim outputData(LBound(inputData, 1) To UBound(inputData, 1), LBound(inputData, 2) To UBound(inputData, 2) + 2) 

      Dim i As Long 
      Dim j As Long 
      ' Loop through rows 
      For i = LBound(inputData, 1) To UBound(inputData, 1) 
       ' Loop through columns 
       For j = LBound(inputData, 2) To UBound(inputData, 2) 
        ' Essentially, just copy the data 
        outputData(i, j) = inputData(i, j) 
       Next 
      Next 

      Dim offSetValue As Long 
      If LBound(outputData, 2) = 1 Then offSetValue = -1 
      ' For your purposes I will use hardcoded indices here, but it is far more ideal to manage this in a more flexible manner 
      For i = LBound(outputData, 1) To UBound(outputData, 1) 
       outputData(i, FIRST_OUTPUT_COL) = outputData(i, FIRST_INPUT_COL) - outputData(i, SECOND_INPUT_COL) 
       outputData(i, SECOND_OUTPUT_COL) = outputData(i, FIRST_OUTPUT_COL) - outputData(i, THIRD_INPUT_COL) 
       If LessThanMargin(outputData(i, SECOND_OUTPUT_COL)) Then 
        For j = LBound(outputData, 2) To UBound(outputData, 2) 
         ' I start with the output worksheet, and use the 'End(xlUp) to find the first 
         ' non-blank row. I then iterate columnwise and add values to the row beneath it. 
         ' The offSetValue variable ensures I am not skipping any cells if the array 
         ' is 1-Based versus the default 0-Base. 
         marginReport.Range("A1048576").End(xlUp).Offset(1, j + offSetValue).value = outputData(i, j) 
        Next 
       End If 
      Next 

      OutputArray outputData, targetWorksheet, "UpdatedData_" & UCase(Replace(targetWorksheet.Name, " ", "_")) 
     End If 
    Next 
End Sub 
' I am just checking for a negative number here, but change this to use the logic you need 
Public Function LessThanMargin(ByVal InputValue As Double) 
    LessThanMargin = InputValue < 0 
End Function 
Public Sub OutputArray(ByVal InputArray As Variant, ByVal InputWorksheet As Worksheet, ByVal TableName As String) 

    Dim AddLengthH As Long 
    Dim AddLengthW As Long 

    If NumberOfArrayDimensions(InputArray) = 2 Then 
     If LBound(InputArray, 1) = 0 Then AddLengthH = 1 
     If LBound(InputArray, 2) = 0 Then AddLengthW = 1 

     Dim r As Range 
     If Not InputWorksheet Is Nothing Then 
      With InputWorksheet 
       .Cells.Clear 
       Set r = .Range("A1").Resize(UBound(InputArray, 1) + AddLengthH, UBound(InputArray, 2) + AddLengthW) 
       r.value = InputArray 
       .ListObjects.Add(xlSrcRange, r, , xlYes).Name = TableName 

       With .ListObjects(1).Sort 
        .Header = xlYes 
        .MatchCase = False 
        .Orientation = xlTopToBottom 
        .SortMethod = xlPinYin 
        .Apply 
       End With 
      End With 
     End If 
    End If 
End Sub 

我使用数组,因为它们对使用Excel-公式处理数据时都远远更有效地解决问题。虽然这不太可能在〜200行的项目中提高性能,但当处理数千行甚至更多时,它会产生巨大的差异。

我也使用常量作为列位置,以便于您在未来调整这些参数。尽管如此,即使是常数(为此目的)也是一种可怕的习惯,所以不习惯它们。了解如何计算数据的位置。

最后,请(对于所有程序化的爱)不要复制和粘贴此代码,并且永不回头。我把它放在这里供你(和其他人)从中学习。不是因为它是一种快速修复。我希望你能用它来增长。

+0

布兰登,感谢您花时间解决问题。我将逐步完成所有代码,并且可能会提出太多问题,自上星期五以来我一直只使用这种语言。最终,我希望能够拥有像您所说的那样的动态系统。我意识到这将会有更多的时间和我的研究。你能否给我提供一些关于如何更好地向社区提出我的问题的方法?我想学习,而不只是把东西交给我。什么是最好的方式来解决这个问题?另外,你有一个VB的最喜欢的资源? –

+0

@KimberlySmelt无后顾之忧。我也曾经在你的鞋子里,这就是为什么我现在想要帮助别人的原因。就VBA资源而言,最大的资源将是您投入VBA学习的时间。我知道这听起来很蹩脚,但即使有我触手可及的所有资源,没有什么比教我解决我不知道如何解决问题更好的教训了。除此之外,YouTube有一些非常好的资源,你也可以在SO上找到其他人遇到同样问题的帖子,你试图克服。 –

+0

您也可以将代码放在codereview.stackexchange.com上,以获取其他开发人员的建议。最后,你花更多的时间学习,你会变得越好。我在六个月前才开始编写VBA,但我现在写的项目现在无法想象成为可能。总之,对于一周前开始学习的人来说,你做得很好。只要坚持下去。对于可以被问到的问题类型,一般来说你的代码应该被打破,你应该无法自己修复它。这就是SO(通常)出现的地方。 –