Dynamics CRM 2011编程系列(38):调用表格的神器(GhostHook)

Dynamics CRM 2011编程系列(38):调用表格的神器(GhostHook)

Dynamics CRM 2011编程系列(38):调用报表的神器(GhostHook)

     本文分享一个工具“GhostHook”,该工具可以彻底解决调用报表的问题。在使用它加载报表的时候,我们传递给报表的参数可以以Get的方式进行传递,“GhostHook”接受到参数后将模拟用户的输入和提交操作。

     来看看“GhostHook”的用法吧:

操作步骤

Dynamics CRM 2011编程系列(38):调用表格的神器(GhostHook)

图1

Dynamics CRM 2011编程系列(38):调用表格的神器(GhostHook)

图2

Dynamics CRM 2011编程系列(38):调用表格的神器(GhostHook)

图3

Dynamics CRM 2011编程系列(38):调用表格的神器(GhostHook)

图4

Dynamics CRM 2011编程系列(38):调用表格的神器(GhostHook)

图5

Dynamics CRM 2011编程系列(38):调用表格的神器(GhostHook)

图6

Dynamics CRM 2011编程系列(38):调用表格的神器(GhostHook)

图7

 

使用到的代码

GhostHook.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="GhostHook.aspx.cs" Inherits="GhostHook" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>GhostHook</title>
</head>

<script language="javascript" type="text/javascript">
    /*
        作者:GhostBear
        制作日期:2012年8月25日
        博客地址:Http://blog.csdn.net/ghostbear
        简介:接收服务器端传递过来的参数并模拟用户对报表进行输入提交操作。
    
    */

    document.onreadystatechange = oncomplete;


    function oncomplete() {
        if (document.readyState == "complete") {
            Go();
        }
    }

    function Go() {

        var tmp = document.getElementById("report").contentWindow.document.getElementById("resultFrame").contentWindow.document.getElementsByTagName("input").length;
        if (tmp == 0) {
            setTimeout("Go()", 1000);
        }
        else {
            var paramPnl = document.getElementById("report").contentWindow.document.getElementById("resultFrame").contentWindow;
            var paramElements = new Array();
            var inputElements = paramPnl.document.getElementsByTagName("input");
            var ddlElements = paramPnl.document.getElementsByTagName("select");
            var boolElements = paramPnl.document.getElementsByTagName("label");
            var submitButton = paramPnl.document.getElementById("reportViewer_ctl04_ctl00");
            var paramExp = /^reportViewer_ctl04_ctl(\d{2})_(txtValue|rbTrue|rbFalse|ddValue)$/;
            var paramValueString = "<%=ParameterValueString%>";
            var paramValueArray = paramValueString.split(';');
            var ddlButtonExp = /^reportViewer_ctl04_ctl\d{2}_ddDropDownButton$/;
            var ddlItemExp = "^reportViewer_ctl04_ctl($NUM$)_divDropDown_ctl\\d{2}$";

            Parameter = function (pType, pDom, pNo) {
                this.ParameterType = pType;
                this.InputDom = pDom;
                this.ParameterNo = pNo;
            }


            //筛选输入类型为文本框的参数
            for (var i in inputElements) {
                if (inputElements[i].id != undefined) {
                    if (paramExp.test(inputElements[i].id)) {
                        if (inputElements[i].nextSibling != null && ddlButtonExp.test(inputElements[i].nextSibling.id)) {//筛选下拉列表类型输入参数
                            var pNo = inputElements[i].id.match(paramExp)[1];
                            var curChkExp = new RegExp(ddlItemExp.replace("($NUM$)", pNo));
                            var curParams = new Array();
                            for (var j = 0; j < inputElements.length; j++) {
                                if (inputElements[j].id != undefined && curChkExp.test(inputElements[j].id)) {
                                    curParams.push(inputElements[j]);
                                }
                            }

                            var p = new Parameter("ddl", curParams, pNo);
                            paramElements.push(p);
                        }
                        else {//筛选文本框类型输入参数
                            var pNo = inputElements[i].id.match(paramExp)[1];
                            var p = new Parameter("textbox", inputElements[i], pNo);
                            paramElements.push(p);
                        }

                    }
                }

            }
            //筛选输入类型为布尔的参数
            var tmpBoolArray = new Array();
            for (var i = 0; i < boolElements.length; i++) {
                if (boolElements[i].htmlFor != undefined) {
                    if (paramExp.test(boolElements[i].htmlFor)) {

                        tmpBoolArray.push(boolElements[i].previousSibling);
                    }
                }
            }
            tmpBoolArray.sort(function (n1, n2) {
                var no1 = parseInt(n1.id.match(paramExp)[1]);
                var no2 = parseInt(n2.id.match(paramExp)[1]);
                return no1 < no2;
            });

            for (var i = 0; i < tmpBoolArray.length; i = i + 2) {
                var pNo = tmpBoolArray[i].id.match(paramExp)[1];
                var p = new Parameter("bool", [tmpBoolArray[i], tmpBoolArray[i + 1]], pNo);
                paramElements.push(p);
            }

            //筛选输入类型为下拉列表的参数
            for (var i = 0; i < ddlElements.length; i++) {
                if (ddlElements[i].id != undefined) {
                    if (paramExp.test(ddlElements[i].id)) {
                        var pNo = ddlElements[i].id.match(paramExp)[1];
                        var p = new Parameter("select", ddlElements[i], pNo)
                        paramElements.push(p);
                    }
                }
            }

            //为参数排序
            var tmpElement;
            var tmpIndex
            for (var i = 0; i < paramElements.length; i++) {
                tmpIndex = i;
                for (var j = i + 1; j < paramElements.length; j++) {
                    var n1 = paramElements[tmpIndex].ParameterNo;
                    var n2 = paramElements[j].ParameterNo;
                    if (n1 > n2) {
                        tmpIndex = j;
                    }
                }
                if (tmpIndex != i) {
                    tmpElement = paramElements[i];
                    paramElements[i] = paramElements[tmpIndex];
                    paramElements[tmpIndex] = tmpElement;
                }
            }




            //模拟用户录入参数
            for (var i = 0; i < paramElements.length; i++) {
                switch (paramElements[i].ParameterType) {
                    case "textbox":
                        paramElements[i].InputDom.value = paramValueArray[i];
                        break;
                    case "bool":
                        var selectedValue = eval(paramValueArray[i]);
                        if (selectedValue) {
                            if (paramElements[i].InputDom[0].id.match(/rbTrue/)) {
                                paramElements[i].InputDom[0].checked = "checked";
                            }
                            else {
                                paramElements[i].InputDom[1].checked = "checked";
                            }
                        }
                        else {
                            if (paramElements[i].InputDom[0].id.match(/rbFalse/)) {
                                paramElements[i].InputDom[0].checked = "checked";
                            }
                            else {
                                paramElements[i].InputDom[1].checked = "checked";
                            }
                        }


                        break;
                    case "select":
                        var options = paramElements[i].InputDom.getElementsByTagName("option");
                        var selectedValue = paramValueArray[i];
                        for (var j = 0; j < options.length; j++) {
                            if (options[j].innerText == selectedValue) {
                                options[j].selected = "selected";
                                break;
                            }
                        }
                        break;
                    case "ddl":

                        var chkItems = paramElements[i].InputDom;
                        var selectedValue = paramValueArray[i].split(',');
                        for (var k = 0; k < chkItems.length; k++) {
                            for (var m = 0; m < selectedValue.length; m++) {
                                if (chkItems[k].nextSibling.innerText == selectedValue[m]) {
                                    chkItems[k].checked = "checked";
                                    chkItems[k].onclick(this);
                                    break;
                                }
                            }
                        }
                        break;
                    default:
                        break;
                }

            }
            //模拟用户提交操作
            submitButton.click();
        }

    }
    
    
</script>

<frameset>
    <frame rows="100%" cols="100%" name="report" id="report" src="../../test/crmreports/viewer/viewer.aspx?action=filter&helpID=<%=RDL_Name%>&id=<%=RDL_Id%>" ></frame>
</frameset>
</html>


GhostHook.aspx.cs

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;
public partial class GhostHook : System.Web.UI.Page
{
    protected string ParameterValueString;
    protected string RDL_Id = string.Empty;
    protected string RDL_Name = string.Empty;

    protected void Page_Load(object sender, EventArgs e)
    {

        Dictionary<string, string> paramTbl = new Dictionary<string, string>();

        //参数的格式:ReportView.aspx?p1=123&p2=5678
        foreach (string p in Request.QueryString.AllKeys)
        {
            if (p == "RDL_Id")
            {
                RDL_Id = Request.QueryString[p];
                continue;
            }
            if (p == "RDL_Name")
            {
                RDL_Name = Request.QueryString[p];
                continue;
            }
            paramTbl.Add(p, Request.QueryString[p]);
        }

        if (string.IsNullOrEmpty(RDL_Id) || string.IsNullOrEmpty(RDL_Name))
        {
            Response.Clear();
            Response.Write("需要提供参数“RDL_Id”和“RDL_Name”。");
        }

        for (int i = 1; i <= paramTbl.Count; i++)
        {
            ParameterValueString += string.Format("{1}", "p" + i.ToString(), paramTbl["p" + i.ToString()]);
            if (i != paramTbl.Count)
            {
                ParameterValueString += ";";
            }
        }

      

    }
}


 

 

小结

  GhostHook虽然比较强大,但还是有些小弊端:

1.受Get传参的影响,传递参数的大小有限制。(好像是2048个字符,不知道是不是?)

2.JavaScript脚本中的GO()函数是通过轮询的方式来运行的(setTimeout)。如果能将它挂在GhostHook.aspx中嵌入的frame页面的onreadystatechange中就完美了。(大家有没好的建议?)

 

 

资源下载

本章使用的报表

1楼orapple20113天前 09:53
真是太强悍了,没有做不到,只有想不到啊