简体   繁体   English

Excel VBA:查找当前行号并按条件插入行

[英]Excel VBA: Locating Current Row Number and Inserting a Row on Condition

I am currently writing a macro that literally compares line-by-line values between Excel and another program. 我目前正在编写一个宏,该宏可以逐字比较Excel和另一个程序之间的逐行值。 99% of the time, when there is a discrepancy it is because a transaction was never added. 99%的情况下,出现差异时是因为从未添加过交易。 So while this macro is comparing these values, upon a discrepancy finding, I would like it to add a new "row" (however, not an entire row, only from A_:K_ , where the _ is whatever row number the active cell is). 因此,当此宏比较这些值时,发现有差异时,我希望它添加一个新的“行”(但是,不是整个行,仅来自A_:K_ ,其中_是活动单元格所在的行号) )。 This will allow me to simply go into Excel, type in the transaction, then press OK on the macro and carry on. 这将使我可以简单地进入Excel,键入事务,然后在宏上按OK并继续。 My macro is actually pretty simple and short & to the point, so I can just go ahead and post the entire thing here so to possibly provide a better understanding of what is happening. 我的宏实际上很简单,而且很简短,因此,我可以继续将整个事情发布到这里,以便可能更好地了解正在发生的事情。 And I am not doing this in Excel's VBA, I am doing this in the other program's VBA, and appXL is Excel's object as a function: 而且我不在Excel的VBA中执行此操作,而是在其他程序的VBA中执行此操作,而appXL是Excel的函数对象:

Function appXL As Object
    Set appXL = GetObject(, "Excel.Application")
End Function

The Main Macro: 主宏:

Sub FeeBrdVerifier
    On Error Resume Next
    With InitSession
        Dim iComm As Currency   ' Compare this with Excel's data
        Dim sComm As String     ' Needed string to allow app to stop at end of report
        Dim xL As Currency      ' Compare this with Host's data
        Dim Counter As Byte     ' Counter for the loop (need to do a new page)
        Dim r As Byte           ' Row # on the page
        Dim Page As Byte

        Page = 1
        Debug.Print "Page # " & Page & vbNewLine & "========="
        Counter = 0     ' 19 unique lines in transaction board per page

        appXL.Workbooks("2016 FEE BOARD.xlsx").Activate
        appXL.Range("J2").Select    'Starting point of the transaction amounts
        r = 3

        Do
            Counter = Counter + 1
            .Copy 69, r, 78, r      ' This copies text from host app, consider it a 'cell'
            sComm = Clipboard
            iComm = CCur(sComm)
            xL = appXL.ActiveCell.Value
            appXL.ActiveCell.Offset("1", "0").Select
            Debug.Print "# [" & Format(Counter,"00") & "].. sComm = [" & sComm & "] ... Excel Value = [" & xL & "]"
            If iComm <> xL Then
                .SetSelection 0, r, 80, r   'Highlights the row in host app that doesnt match
    '           appXL.      '<<<< where I need assistance, insert line and shift down
                MsgBox "Did not match..."
                .ClearSelection     'Get rid of highlight after msgbox cleared
            End If
            r = r + 1               ' This allows the loop to copy the next line
            If Counter = 19 Then
                Page = Page + 1
                Counter = 0
                .Output E           ' E is a function I use for the Return Key
                Sleep 250           ' Waiting for next page to load
                r = 3               ' On a new page now, go back to the top
                Debug.Print vbNewLine & "Page # " & Page & vbNewLine & "========="
            End If
        Loop Until sComm = ""   ' Reached last transaction
    End With
End Sub

So, to recap, if the active cell was J495 , manually what I would do is select the range of A495:K495 , right-click selection, click Insert , then click Shift Cells Down . 因此,回顾一下,如果活动单元格是J495 ,那么我要手动执行的操作是选择A495:K495的范围,右键单击选择,单击“ Insert ,然后单击Shift Cells Down Now I just need this to be automated. 现在,我只需要将其自动化即可。 Eventually I plan to also automate filling in the missing data, but this part is what comes first (or else I would just continue to manually do this myself). 最终,我计划还自动填充丢失的数据,但这是第一部分(否则,我将自己继续手动执行此操作)。

As an added bonus , I would appreciate if someone could also explain how to grab the current row number where the line was inserted to so I can add this line number to the debugger window - but I can live without if necessary 作为额外的好处 ,如果有人能解释如何获取插入行的当前行号,我将不胜感激,这样我就可以将该行号添加到调试器窗口中,但是如果没有必要,我可以住

This should work for what you are trying to do 这应该适合您尝试做的事情

  .SetSelection 0, r, 80, r 
    appXL.ActiveSheet.Range(appXL.cells(appXL.activecell.Row,1),appXL.cells(appXL.activecell.Row,11)).Insert Shift:=xlDown
    MsgBox "Did not match..." & " the current row number is : " & appXL.ActiveCell.Row()



  'Then move to next row to continue the loop
    appXL.ActiveCell.Offset(1)

Per the comments above, I'd take @cyboashu's answer and run with it a little bit. 根据上面的评论,我会用@cyboashu的答案并稍作处理。 Converting the code from using the Active* objects and using Activate and Select will make the code much easier to maintain and extend. 通过使用Active*对象以及使用ActivateSelect来转换代码将使代码更易于维护和扩展。 Here's a sample refactoring to use absolute references instead (to give you an idea). 这是一个重构示例,它使用绝对引用代替(给您一个想法)。 This is obviously untested - I don't even know what application it's running under. 这显然未经测试-我什至不知道它在运行什么应用程序。 :-P :-P

Sub FeeBrdVerifier()
    On Error Resume Next
    With InitSession
        Dim iComm As Currency   ' Compare this with Excel's data
        Dim sComm As String     ' Needed string to allow app to stop at end of report
        Dim xL As Currency      ' Compare this with Host's data
        Dim Counter As Byte     ' Counter for the loop (need to do a new page)
        Dim r As Byte           ' Row # on the page
        Dim Page As Byte

        Page = 1
        Debug.Print "Page # " & Page & vbNewLine & "========="
        Counter = 0     ' 19 unique lines in transaction board per page

        'Get a reference to the ActiveSheet
        Dim sheet As Object
        Set sheet = appXL.Workbooks("2016 FEE BOARD.xlsx").ActiveSheet

        r = 3

        Dim currentRow As Long
        currentRow = 2 'Starting point of the transaction amounts in Column J (ordinal is 10)
        Do
            Counter = Counter + 1
            .Copy 69, r, 78, r      ' This copies text from host app, consider it a 'cell'
            sComm = Clipboard
            iComm = CCur(sComm)
            xL = sheet.Cells(currentRow, 10).Value
            currentRow = currentRow + 1
            Debug.Print "# [" & Format(Counter, "00") & "].. sComm = [" & sComm & "] ... Excel Value = [" & xL & "]"
            If iComm <> xL Then
                .SetSelection 0, r, 80, r   'Highlights the row in host app that doesnt match
                sheet.Range(sheet.Cells(currentRow, 1), sheet.Cells(currentRow, 11)).Insert
                MsgBox "Did not match..."
                .ClearSelection     'Get rid of highlight after msgbox cleared
            End If
            r = r + 1               ' This allows the loop to copy the next line
            If Counter = 19 Then
                Page = Page + 1
                Counter = 0
                .Output E           ' E is a function I use for the Return Key
                Sleep 250           ' Waiting for next page to load
                r = 3               ' On a new page now, go back to the top
                Debug.Print vbNewLine & "Page # " & Page & vbNewLine & "========="
            End If
        Loop Until sComm = vbNullString   ' Reached last transaction
    End With
End Sub

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

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