二开案例.执行计划.获取并保存账表数据

【应用场景】需要周期性的将账表在某个过滤方案下的所有数据保存起来,提供给第三方应用使用。
【案例演示】实现一个定时任务,定期将存货收发存汇总表和存货收发存汇总表的指定过滤方案下的数据存储到指定的表中。
执行计划入门演示可参考:
【二开案例.执行计划.从零开发执行计划】https://vip.kingdee.com/article/109330633939560192
【注意】此案例代码仅适用于简单账表,不适用于分页账表。

【实现步骤】
<1>编写执行计划,代码如下。
using Kingdee.BOS;
using Kingdee.BOS.App.Core;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Report;
using Kingdee.BOS.Log;
using Kingdee.BOS.Model.ReportFilter;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Serialization;
using Kingdee.BOS.Util;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
namespace Jac.XkDemo.BOS.App.PlugIn
{
/// <summary>
/// 【执行计划】获取并保存账表数据
/// https://vip.kingdee.com/article/109345564135072000
/// </summary>
public class GetReportDataScheduleService : IScheduleService
{
/// <summary>
/// 执行计划
/// </summary>
/// <param name="ctx"></param>
/// <param name="schedule"></param>
public void Run(Context ctx, Schedule schedule)
{
if (schedule.Parameters.IsNullOrEmpty())
{
return;
}
var parameters = JsonConvert.DeserializeObject<List<RptHelper.SaveReportDataParameter>>(schedule.Parameters);
foreach (var parameter in parameters)
{
try
{
RptHelper.SaveReportData(ctx, parameter);
}
catch (Exception ex)
{
var errMsg = string.Format("读取报表数据异常:{0}", JsonConvert.SerializeObject(parameter));
Logger.Error("Jac", errMsg, ex);
}
}
}
}
/// <summary>
/// 账表辅助类
/// </summary>
public class RptHelper
{
#region method
/// <summary>
/// 保存账表数据
/// </summary>
/// <param name="scheduleCtx">上下文</param>
/// <param name="parameter">保存账表数据参数</param>
/// <param name="typeId"></param>
public static void SaveReportData(Context scheduleCtx, SaveReportDataParameter parameter, string typeId = "0")
{
var ctx = GetContext(scheduleCtx, parameter.UserName);
// 读取账表数据(存货收发存汇总表)
var reportData = GetReportData(ctx, parameter);
// 将账表数据保存到指定的表中
#region 方式1:直接在数据库拷贝一份,如果不再加工数据,推荐用此方式
if (typeId == "0")
{
var sql = string.Format(@"/*dialect*/
IF EXISTS(SELECT * FROM sys.objects WHERE object_id=OBJECT_ID(N'{0}') AND type IN (N'U'))
DROP TABLE {0}
SELECT * INTO {0} FROM {1}", parameter.TableName, reportData.DataSource.TableName);
DBUtils.Execute(ctx, sql);
}
#endregion
#region 方式2:使用内存表批量插入数据库
else if (typeId == "1")
{
// 创建临时表
var createTableSql = BuildCreateTableSql(reportData.DataSource, parameter.TableName);
DBUtils.Execute(ctx, createTableSql);
// 将账表数据存入临时表
var dataSource = reportData.DataSource.Clone();
dataSource.TableName = parameter.TableName;
foreach (DataRow row in reportData.DataSource.Rows)
{
dataSource.Rows.Add(row.ItemArray);
}
DBUtils.BulkInserts(ctx, dataSource);
}
#endregion
}
/// <summary>
/// 获取简单账表数据
/// </summary>
/// <param name="ctx">上下文</param>
/// <param name="parameter">账表数据保存参数</param>
/// <returns></returns>
public static IReportData GetReportData(Context ctx, SaveReportDataParameter parameter)
{
var metaDataService = new MetaDataService();
var filterMetadata = new CommonFilterService().GetFilterMetaData(ctx, ""); //加载过滤元数据。
var reportMetadata = (FormMetadata)metaDataService.Load(ctx, parameter.RptFormId); //加载账表元数据
var reportFilterMetadata = (FormMetadata)metaDataService.Load(ctx, parameter.RptFilterFormId); //加载账表的过滤窗体的元数据。
var reportFilterServiceProvider = reportFilterMetadata.BusinessInfo.GetForm().GetFormServiceProvider();
var model = new SysReportFilterModel();
model.SetContext(ctx, reportFilterMetadata.BusinessInfo, reportFilterServiceProvider);
model.FormId = reportFilterMetadata.BusinessInfo.GetForm().Id;
model.FilterObject.FilterMetaData = filterMetadata;
model.InitFieldList(reportMetadata, reportFilterMetadata);
model.GetSchemeList();
var entity = model.Load(parameter.SchemeId);
var dyn = DeserializeCustomFilter(reportFilterMetadata.BusinessInfo, entity.CustomFilterSetting);
model.DataObject = dyn;
var filter = model.GetFilterParameter();
IRptParams rptParams = new RptParams();
rptParams.FormId = reportMetadata.BusinessInfo.GetForm().Id;
rptParams.FilterParameter = filter;
rptParams.FilterFieldInfo = model.FilterFieldInfo;
rptParams.ParameterData = GetUserParamters(ctx, reportMetadata.BusinessInfo);
rptParams.IsOnlyQuerySumData = GetOnlyDspSumData(rptParams.ParameterData);
rptParams.CurrentPosition = 0;
rptParams.StartRow = 1;
rptParams.EndRow = int.MaxValue;
var param = new ReportServiceParameter(ctx, reportMetadata.BusinessInfo, Guid.NewGuid().ToString(), rptParams);
return new SysReportService().GetReportData(param);
}
/// <summary>
/// 获取指定用户上下文
/// </summary>
/// <param name="ctx">上下文</param>
/// <param name="userName">用户名</param>
/// <returns></returns>
public static Context GetContext(Context ctx, string userName)
{
if (userName.IsNullOrEmpty())
{
return ctx;
}
var userId = DBUtils.ExecuteScalar(ctx, string.Format("SELECT FUSERID FROM T_SEC_USER WHERE FNAME='{0}'", userName), 0);
if (userId <= 0)
{
return ctx;
}
var newCtx = (Context)ctx.Clone();
newCtx.UserId = userId;
newCtx.UserName = userName;
return newCtx;
}
/// <summary>
/// 获取过滤窗体的自定义参数
/// </summary>
/// <param name="businessInfo">过滤窗体元数据</param>
/// <param name="xml">自定义过滤参数XML</param>
/// <returns></returns>
private static DynamicObject DeserializeCustomFilter(BusinessInfo businessInfo, string xml)
{
var binder = new DynamicObjectDcxmlBinder(businessInfo);
binder.OnlyDbProperty = false;
var target = new DcxmlSerializer(binder);
binder.Culture = CultureInfo.InvariantCulture;
target.ColloctionIgnorePKValue = true;
var obj = (DynamicObject)target.DeserializeFromString(xml);
return obj;
}
/// <summary>
/// 获取账表的用户参数
/// </summary>
/// <param name="ctx">上下文</param>
/// <param name="reportBusinessInfo"></param>
/// <returns></returns>
private static DynamicObject GetUserParamters(Context ctx, BusinessInfo reportBusinessInfo)
{
string formId = reportBusinessInfo.GetForm().ParameterObjectId;
if 二开案例.执行计划.获取并保存账表数据
【应用场景】需要周期性的将账表在某个过滤方案下的所有数据保存起来,提供给第三方应用使用。【案例演示】实现一个定时任务,定期将存货收...
点击下载文档文档为doc格式
声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。如若本站内容侵犯了原著者的合法权益,可联系本站删除。
上一篇
已经是第一篇



