用過 ActiveReports for .Net (以下簡稱AR)的都知道它的優勢(可代碼化),這樣就提供了很多報表功能開發的空間給程序員。
不多說了,下面將通過我的一個EPR軟件來介紹一下實現 AR 2.0 的報表本地化功能(主要通過UI貼圖+講解方式):
開發環境:VS2005 .Net 2.0 + C# + SQL2005 + AR 2.0
=========================================================

講解一下如何實現這幾種本地化語言:
1,報表預定義(快速!) [Default]
就是指實例化報表時不應用本地化設置;
2,CIMS本地化設置(推薦!)(System)
隨主系統的本地化設置一樣;
3,簡體中文(Chinese SimplifIEd)
4,繁體中文(Chinese Traditional)
ReportLocal 類 定義一個屬性:
這個屬性在ReportLocal類實例化代入,來自主系統用戶權限控制,如果你的程序沒有相關權限控制可忽略。
這個Active屬性用來表示將要使用的本地化語言:
這些屬性,函數很關鍵,主要收集可以本地化的報表組件(未定義DataFIEld屬性的):
foreach ( rs in rpt.Sections)
{
if (rs.Name == sectionNameOrType) break;
if (type == rs.Type) break;
}
}
catch {
all = true;
break;
}
}
if (all || (rs == null)) {
foreach ( rs in rpt.Sections)
這是ReportControlInfo類(用於收錄組件的相關參數):
public class ReportControlInfo 
...{
protected string m_text;
protected string m_dataFIEld;
protected object m_section;
protected object m_parent;
public ReportControlInfo(string text)
...{
m_text = text;
}
public ReportControlInfo(string text, object section) 
...{
m_text = text;
m_section = section;
}
public ReportControlInfo(string text, string dataFIEld) 
...{
m_text = text;
m_dataField = dataFIEld;
}

/**//// <summary>
/// 獲取或設置 組件預定義了的文本
/// </summary> 
string Text ...{ 
get ...{ return m_text; } 
set ...{ m_text = value; }
}

/**//// <summary>
/// 獲取或設置 用於關聯本地化設置的‘字段名’
/// </summary> 
public string DataFIEld ...{ 
get ...{ return m_dataFIEld; } 
set ...{ m_dataFIEld = value; }

/**//// <summary>
/// 獲取或設置 組件的父容器(PageHeader,GroupHeader...),一般可不設置
/// </summary> 
public object Parent ...{ 
get ...{ return m_parent; } 
set ...{ m_parent = value; }
} 
/**//// <summary>
/// 獲取或設置 組件所在的節(Report.Section),可以是SectionName OR SectionType
/// </summary> 
Section ...{ 
get ...{ return m_section; } 
set ...{ m_section = value; }
}
}
=================================
下面將是實現“報表本地化關聯”功能的核心:
為於實現報表同主系統使用一致的本地化定義,下面部分是必須的!
系統的本地化資源編輯器(由於此ERP的應用關系,編輯器中增加了對應用人的權限控制),源代碼不提供:

這是 關聯系統本地化設置 的報表本地化配置器:
解釋一下各字段作用:
所屬區域:指要本地化的組件所在的Section,如果為空,則為公共設置,任何報表都會搜索這些關聯設置;
字段名:一般為數據表的ColumnName,要同“本地化編輯器”裡的DataFIEld定義一致;
組件名:將本地化的AR.Control,應於實際報表設計時一致,如果報表做了更改,可使用“批量修復”功能來自動修復refContrlName;
默認文本:AR.Control 預定義的Text,如果用戶想始終使用這個DefaultText,只需要定義後鉤選“僅使用默認標題”;
備注:不用解釋了。
“報表效果預覽”只是應用了最上面的參數設置。

下面,錄制了一個“批量創建”報表組件的本地化關聯設置的動畫(文件太大!只能用GIF格式上傳了,UI有失真):

索引關聯設置類:
using System;
using System.Text;
using System.Data;
using System.Data.SqlClIEnt;
namespace CIMS.Report
...{
public class ReportsLocalization : IDisposable


Const#region Const
public static string[] Sections
...{
get
...{
return new string[] ...{
"ReportHeader",
"PageHeader",
"GroupHeader",
"Detail",
"ReportFooter",
"PageFooter",
"GroupFooter",
"Unknown!"};
}
}
public const string COL_DATAFIELD = "字段名";
public const string COL_REPORTID = "報表編碼";
public const string COL_SECTIONNAME = "所屬區域";
public const string COL_CONTROLNAME = "組件名";
public const string COL_CONTROLTEXT = "默認文本";
public const string DATATABLE_NAME = "ReportsLocalization";
#endregion

Variables#region Variables
protected string m_reportID = string.Empty;
protected string m_activeDBForm = string.Empty;
protected Document.ReportLocalizable reportLocal = null;
protected EnToolTips refLocal = null;
protected DataVIEw dv = null;
#endregion

Init#region Init
<summary>
/// 實例化本地化報表關聯設置加載類
/// </summary>
/// <param name="reportID">報表枚舉成員(ReportsAssembly.MemberID)</param>
public ReportsLocalization(string reportID):this(reportID,string.Empty) ...{ }
/**//// <summary>
/// 實例化本地化報表關聯設置加載類
/// </summary>
/// <param name="reportID">報表枚舉成員(ReportsAssembly.MemberID)</param>
/// <param name="dbFormName">將應用自定義本地化報表的數據模塊(如果為空,則表示將應用到所有模塊)</param>
public ReportsLocalization(string reportID, string dbFormName)
...{
if (string.IsNullOrEmpty(reportID)) ...{ throw ne("報表成員未指定!"); }
m_reportID = reportID;
m_activeDBForm = dbFormName;
this.OnInit();
}
protected void OnInit()
...{
if (Common.Common.get_CIMSReadOnly(false)) return;
reportLocal = new CIMS.Document.ReportLocalizable(ActiveDBForm);
refLocal = new EnToolTips(ActiveDBForm);
this.FillData();
}
protected void FillData()
...{
string paramReportID = "@ReportID";
SqlDataAdapter sda = new SqlDataAdapter("SELECT ReportID AS " + COL_REPORTID + ", DataField AS " + COL_DATAFIELD + ", SectionName AS " + COL_SECTIONNAME + ", ControlName AS " + COL_CONTROLNAME + ", ControlText AS " + COL_CONTROLTEXT + ", Lock AS " + Utils.LOCK + " FROM " + DATATABLE_NAME + " Where ReportID Is Null Or ReportID = " + paramReportID + " Order By ReportID", Common.SqlHelper.ConnectionBase.CONCIMS);
&n sda.SelectCommand.Parameters.Add(paramReportID, SqlDbType.VarChar, 50).Value = this.ReportID;
DataTable dt = new DataTable(DATATABLE_NAME);
using (sda)
...{
dt.BeginLoadData();
sda.Fill(dt);
dt.EndLoadData();
}
dv = dt.DefaultVIEw;
}
#endregion

Properties#region PropertIEs
/**//// <summary>
/// 獲取 本地化定位器
/// </summary>
EnToolTips Localizer ...{ get ...{ return refLocal; } }
/**//// <summary>
/// 獲取 報表枚舉成員(ReportsAssembly.MemberID)
/// </summary>
public string ReportID ...{get ...{ return m_reportID; }}
/**//// <summary>
/// 獲取將應用報表本地化關聯設置的數據模塊(如果為空,則表示將搜索所有模塊的本地化設置資源)
/// </summary>
public string ActiveDBForm ...{ get ...{ return m_activeDBForm; } }
#endregion

#region Localizable
/**//// <summary>
/// 獲取報表組件(按Control.Name)的本地化關聯設置。不存在設置就返回空:String.Empty
/// </summary>
/// <param name="ctrlName">組件名</param>
/// <returns>不存在設置就返回空:String.Empty</returns>
public string GetLocalText(string ctrlName)
...{
string nameFilter = COL_CONTROLNAME + "=''" + ctrlName + "''";
dv.RowFilter = nameFilter;
if (dv.Count == 0) return string.Empty;
dv.RowFilter += " And " + COL_REPORTID + "=''" + ReportID + "''";//報表成員優先
if (dv.Count > 0) return GetActiveLocalText(dv[0]);
dv.RowFilter = nameFilter + " And " + COL_REPORTID + " IS Null";//搜索公共成員
if (dv.Count > 0) return GetActiveLocalText(dv[0]);
return string.Empty;
}
protected string GetActiveLocalText(DataRowVIEw drv)
bool useDefaultText = Convert.ToBoolean(Common.Common.IsNull(drv[Utils.LOCK], false));
if (useDefaultText) return Common.Common.IsNull(drv[COL_CONTROLTEXT],drv[COL_DATAFIELD]).ToString();//使用默認文本
string dataField = Common.Common.IsNull(drv[COL_DATAFIELD], string.Empty).ToString();
switch (reportLocal.Active)
...{
case ReportLocalizableBase.ReportLocalizableEnum.ChineseSimplifIEd:
return refLocal[dataFIEld];
case ReportLocalizableBase.ReportLocalizableEnum.ChineseTraditional:
return refLocal.ConvertZNString(refLocal[dataFIEld]);
case ReportLocalizableBase.ReportLocalizableEnum.English:
return refLocal.IsExist(dataFIEld) ? refLocal.EnToolTip : string.Empty;
default:
return string.Empty;
}
}

<summary>
///// 獲取報表組件(按Control.Text)的本地化關聯設置
///// </summary>
///// <param name="ctrlText">組件的預設文本</param>
///// <returns></returns>
//public string GetLocalText(string ctrlText)
//{
// dv.RowFilter = COL_CONTROLNAME + "=''" + ctrlName + "''";
//}
//protected bool SetRowFilter(string filter, bool ctrlNameFilter)
//{
// dv.RowFilter = (ctrlNameFilter ? COL_CONTROLNAME : COL_CONTROLNAME) + "=''" + filter + "''";
//}
#endregion

IDisposable#region IDisposable
public void Dispose()
...{
if (Localizer != null) Localizer.Dispose();
if (dv != nul.Dispose();
}
#endregion
}
}
通過上面一些定義,就可以在實例化報表時實現本地化報表了!
先收集本地化組件到Collection,然後遍歷集合並:
最終報表本地化預覽:
