You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VBA批量获取NPI编号:表格数据处理、循环及弹窗点击问题

Solutions for Your NPI Lookup VBA Script

Great question! Let's tackle each of your issues one by one, starting with the blocking security popup, then implementing the row loop, and handling no-search-result scenarios. We'll also cover the recommended XHR approach to avoid IE-related headaches entirely.

1. Automatically Clicking the IE Security Popup

Since you can't disable the IE security prompt via settings, we can use Windows API functions to detect the popup window and simulate a click on the "Yes" button. Add these declarations at the top of your VBA module (outside any subroutine):

Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As LongPtr, ByVal hWnd2 As LongPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr
Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr

Const BM_CLICK = &HF5
Const WAIT_INTERVAL = 500 ' Wait 0.5 seconds between checks
Const MAX_WAIT = 10 ' Max 10 seconds to wait for popup

Then add this helper function to click the "Yes" button:

Sub ClickIEPopupYes()
    Dim popupHWND As LongPtr
    Dim buttonHWND As LongPtr
    Dim waitCounter As Integer
    
    waitCounter = 0
    Do
        ' Look for the IE security popup window (adjust title if yours differs)
        popupHWND = FindWindow(vbNullString, "Internet Explorer Security")
        If popupHWND <> 0 Then
            ' Find the "Yes" button (standard button class name)
            buttonHWND = FindWindowEx(popupHWND, 0, "Button", "Yes")
            If buttonHWND <> 0 Then
                SendMessage buttonHWND, BM_CLICK, 0, 0
                Exit Do
            End If
        End If
        waitCounter = waitCounter + 1
        Sleep WAIT_INTERVAL
    Loop Until waitCounter >= MAX_WAIT
End Sub

2. Loop Through Excel Rows & Fetch NPIs

Modify your existing GetNpi subroutine to iterate over your spreadsheet rows, fill the search fields, and write results to adjacent cells. This example assumes:

  • Last names in column A
  • First names in column B
  • State in column C
  • NPIs written to column D
  • Row 1 is a header row
Sub GetNpi()
    Dim ie As Object
    Dim ieDoc As Object
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim i As Long
    
    ' Set your target worksheet (update the sheet name)
    Set ws = ThisWorkbook.Worksheets("Sheet1")
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    
    ' Initialize IE
    Set ie = New InternetExplorer
    ie.Visible = True
    
    ' Navigate to the lookup site
    ie.navigate "npinumberlookup.org"
    Do While ie.readyState <> READYSTATE_COMPLETE Or ie.Busy
        DoEvents
    Loop
    
    ' Handle initial security popup
    ClickIEPopupYes()
    
    ' Loop through each data row
    For i = 2 To lastRow
        Set ieDoc = ie.document
        
        ' Fill search fields with spreadsheet data
        ieDoc.getElementById("last").Value = ws.Cells(i, "A").Value
        ieDoc.getElementById("first").Value = ws.Cells(i, "B").Value
        ieDoc.getElementById("pracstate").Value = ws.Cells(i, "C").Value
        
        ' Submit the search form
        ieDoc.getElementById("submit").Click
        
        ' Wait for results to load
        Do While ie.readyState <> READYSTATE_COMPLETE Or ie.Busy
            DoEvents
        Loop
        
        ' Extract and write NPI (adjust selector to match site's HTML)
        Dim npiElement As Object
        On Error Resume Next
        Set npiElement = ieDoc.querySelector(".npi-result .npi-value") ' Update this selector if needed
        On Error GoTo 0
        
        If Not npiElement Is Nothing Then
            ws.Cells(i, "D").Value = npiElement.innerText
        Else
            ' Handle no results case
            ws.Cells(i, "D").Value = "No NPI Found"
        End If
        
        ' Navigate back to search page for next iteration
        ie.navigate "npinumberlookup.org"
        Do While ie.readyState <> READYSTATE_COMPLETE Or ie.Busy
            DoEvents
        Loop
        ClickIEPopupYes() ' Rehandle popup if it reappears
    Next i
    
    ' Cleanup
    ie.Quit
    Set ie = Nothing
    MsgBox "NPI lookup completed!", vbInformation
End Sub

As suggested, using XHR avoids IE entirely—no popups, faster execution, and more reliable for automation. Here's a complete XHR version:

Sub GetNpiWithXHR()
    Dim xhr As Object
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim i As Long
    Dim postData As String
    Dim responseText As String
    Dim npiStart As Integer
    Dim npiEnd As Integer
    
    Set ws = ThisWorkbook.Worksheets("Sheet1")
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    
    Set xhr = CreateObject("MSXML2.XMLHTTP.6.0")
    
    For i = 2 To lastRow
        ' Construct POST data to match the site's form fields
        postData = "last=" & URLEncode(ws.Cells(i, "A").Value) & _
                   "&first=" & URLEncode(ws.Cells(i, "B").Value) & _
                   "&pracstate=" & URLEncode(ws.Cells(i, "C").Value) & _
                   "&submit=Search"
        
        ' Send POST request to the search endpoint
        xhr.Open "POST", "https://npinumberlookup.org/search", False
        xhr.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
        xhr.send postData
        
        responseText = xhr.responseText
        
        ' Extract NPI from the HTML response
        npiStart = InStr(responseText, "NPI Number:") + Len("NPI Number:")
        If npiStart > 0 Then
            npiEnd = InStr(npiStart, responseText, "<")
            ws.Cells(i, "D").Value = Trim(Mid(responseText, npiStart, npiEnd - npiStart))
        Else
            ws.Cells(i, "D").Value = "No NPI Found"
        End If
    Next i
    
    MsgBox "XHR-based NPI lookup completed!", vbInformation
End Sub

' Helper function to URL-encode form data
Function URLEncode(ByVal str As String) As String
    Dim bytes() As Byte
    Dim i As Integer
    bytes = StrConv(str, vbUnicode)
    For i = 0 To UBound(bytes) Step 2
        If bytes(i) >= 32 And bytes(i) <= 126 And bytes(i) <> 37 Then
            URLEncode = URLEncode & Chr(bytes(i))
        Else
            URLEncode = URLEncode & "%" & Hex(bytes(i)) & Hex(bytes(i + 1))
        End If
    Next i
End Function

Why XHR is Better:

  • No IE instance required, so no security popups or slow browser navigation.
  • Faster execution since it skips rendering HTML.
  • More stable for automated tasks.

内容的提问来源于stack exchange,提问作者josephkane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:09:53