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

如何使用VBA查询Microsoft Dynamics CRM 2011或ASPX中的数据?

听你说的情况,用网页抓取CRM 2011的页面确实会踩很多坑——毕竟CRM的ASPX页面是动态渲染的,还有身份验证、视图状态这些机制拦着,直接扒HTML肯定行不通。其实微软给CRM 2011提供了官方的API接口,用这个来查询数据才是靠谱的方案,下面给你分两种情况说明:

首选方案:使用CRM 2011官方Organization Service API

CRM 2011的Organization Service是基于SOAP的官方接口,专门用来和系统交互数据,完全不需要碰前端页面,直接通过主键查询项目详情才是正确姿势。

步骤说明:

  • 第一步:准备身份验证
    如果你的CRM是内部AD部署,直接用Windows集成身份验证就行;如果是IFD(公网部署),需要处理ADFS的身份验证逻辑。下面的示例用内部AD场景。
  • 第二步:编写VBA代码调用SOAP接口
    先在VBA编辑器里引用Microsoft XML, v6.0(工具→引用),然后用以下代码查询指定主键的项目实体(假设实体逻辑名是new_project,主键字段是new_projectid,需要返回的字段比如new_projectname、new_description):
Sub QueryCRMProject()
    Dim xmlHttp As MSXML2.XMLHTTP60
    Dim soapRequest As String
    Dim crmUrl As String
    Dim projectId As String
    Dim responseXml As MSXML2.DOMDocument60
    Dim node As MSXML2.IXMLDOMNode
    
    ' CRM Organization Service地址(替换成你的CRM地址)
    crmUrl = "http://your-crm-server/XRMServices/2011/Organization.svc"
    ' 要查询的项目主键(替换成实际ID)
    projectId = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
    
    ' 构造SOAP请求
    soapRequest = "<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"">" & _
        "<s:Body>" & _
        "<Retrieve xmlns=""http://schemas.microsoft.com/xrm/2011/Contracts/Services"" xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"">" & _
        "<entityName>new_project</entityName>" & _
        "<id>" & projectId & "</id>" & _
        "<columnSet xmlns:a=""http://schemas.microsoft.com/xrm/2011/Contracts"">" & _
        "<a:AllColumns>false</a:AllColumns>" & _
        "<a:Columns xmlns:b=""http://schemas.microsoft.com/2003/10/Serialization/Arrays"">" & _
        "<b:string>new_projectname</b:string>" & _
        "<b:string>new_description</b:string>" & _
        "</a:Columns>" & _
        "</columnSet>" & _
        "</Retrieve>" & _
        "</s:Body>" & _
        "</s:Envelope>"
    
    Set xmlHttp = New MSXML2.XMLHTTP60
    With xmlHttp
        .Open "POST", crmUrl, False
        .setRequestHeader "Content-Type", "text/xml; charset=utf-8"
        .setRequestHeader "SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Retrieve"
        ' Windows集成身份验证
        .setRequestHeader "Authorization", "Negotiate "
        .send soapRequest
        
        ' 解析返回的XML
        Set responseXml = New MSXML2.DOMDocument60
        responseXml.LoadXML .responseText
        
        ' 提取项目名称和描述
        Set node = responseXml.SelectSingleNode("//*[local-name()='new_projectname']")
        If Not node Is Nothing Then
            Debug.Print "项目名称: " & node.Text
        End If
        
        Set node = responseXml.SelectSingleNode("//*[local-name()='new_description']")
        If Not node Is Nothing Then
            Debug.Print "项目描述: " & node.Text
        End If
    End With
    
    Set xmlHttp = Nothing
    Set responseXml = Nothing
End Sub

注意事项:

  • 替换代码中的crmUrl为你的CRM实际服务地址,实体逻辑名、字段名也要对应你系统中的配置。
  • 如果是IFD部署,需要替换身份验证部分,改用ADFS获取令牌后再调用接口。
备选方案:模拟浏览器操作(仅当API不可用时)

如果因为权限或其他原因没法用API,只能走网页抓取的话,得用VBA模拟IE浏览器操作(CRM 2011对IE兼容性更好),等待页面完全加载后再获取内容,而不是直接看浏览器的"查看源代码"(因为动态渲染的内容只有页面加载完成后才会生成)。

示例代码:

Sub ScrapeCRMProject()
    Dim ie As Object
    Dim projectId As String
    Dim searchInput As Object
    Dim searchButton As Object
    Dim detailElement As Object
    
    Set ie = CreateObject("InternetExplorer.Application")
    projectId = "你的项目编号"
    
    With ie
        .Visible = True ' 调试时可以设为True,上线后改False
        .Navigate "http://your-crm-server/main.aspx?etc=10001&pagetype=entitylist" ' 替换成项目列表页地址
        
        ' 等待页面加载完成
        Do While .Busy Or .ReadyState <> 4
            DoEvents
        Loop
        
        ' 假设搜索框的ID是"new_projectid",搜索按钮ID是"searchButton"
        Set searchInput = .Document.getElementById("new_projectid")
        If Not searchInput Is Nothing Then
            searchInput.Value = projectId
            ' 模拟点击搜索按钮
            Set searchButton = .Document.getElementById("searchButton")
            If Not searchButton Is Nothing Then
                searchButton.Click
                
                ' 等待搜索结果加载
                Do While .Busy Or .ReadyState <> 4
                    DoEvents
                Loop
                
                ' 提取详情,假设项目名称在class为"project-name"的元素里
                Set detailElement = .Document.querySelector(".project-name")
                If Not detailElement Is Nothing Then
                    Debug.Print "项目名称: " & detailElement.innerText
                End If
            End If
        End If
        
        ' 关闭浏览器(可选)
        .Quit
    End With
    
    Set ie = Nothing
    Set searchInput = Nothing
    Set searchButton = Nothing
    Set detailElement = Nothing
End Sub

注意事项:

  • 这个方案非常脆弱,CRM页面的元素ID、类名一旦修改,代码就会失效。
  • 要处理登录逻辑,如果CRM需要手动登录,得在代码里模拟输入用户名密码点击登录按钮。
  • 页面加载等待的逻辑要写完善,避免因为加载未完成导致找不到元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:44:19