C# 服务调用RFC函数获取物料信息,并输出生成Excel文件

这个例子是C#服务调用RFC函数,获取物料的信息,并生成Excel文件

上接文章:C#服务

文章目录

  • 创建函数
  • 创建结构
  • 编写源代码
  • 创建批处理文件
  • 运行结果-成功
  • 部署服务器
  • C#代码
  • 配置文件
  • 注意!!

创建函数

在这里插入图片描述

创建结构

在这里插入图片描述

编写源代码

在这里插入图片描述

创建批处理文件

在这里插入图片描述
在这里插入图片描述

echo %~dp0
%SystemRoot%\Microsoft.NET\Framework64\v4.0.30319\installUtil.exe %~dp0WindowsService1_SAP_RFC.exe
Net Start C#ServerTest
sc config C#ServerTest=auto
pause

在这里插入图片描述

%SystemRoot%\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /u %~dp0WindowsService1_SAP_RFC.exe
pause

运行结果-成功

在这里插入图片描述

部署服务器

在这里插入图片描述

C#代码

using SAP.Middleware.Connector;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Data.OleDb;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Timers;namespace WindowsService1_SAP_RFC
{//创建人:LiuHongyu//创建日期:2024年12月20日//描述:测试C#服务的创建以及和SAP进行通讯,并生成Excel文档public partial class Service1 : ServiceBase{public Service1(){InitializeComponent();}//文件路径private string filePath = ConfigurationManager.AppSettings["FilePath"];//Excel文件路径private string excelFilePath = ConfigurationManager.AppSettings["ExcelFilePath"];//Excel模板文件路径private string excelFileTemplatePath = ConfigurationManager.AppSettings["ExcelFileTemplatePath"];private int n = 1;//计时器Timer timer;//rfc的地址private RfcDestination _rfcDestination;//每天定时器开关private bool dayScheduleSwitch;//每天定时执行的时间private string dayScheduleTime;//每月定时器开关private bool monthScheduleSwitch;//服务启动时调用protected override void OnStart(string[] args){WriteLog(filePath, "启动服务------");InitTimer();}private void InitTimer(){try{WriteLog(filePath, "开始计数------");timer = new Timer(60000);//1分钟//时间间隔到了之后,执行的操作为Executetimer.Elapsed += Execute;//是否重复执行timer.AutoReset = true;  //如果不设置就是只会执行一次//是否执行Elapsed中的事件timer.Enabled = true;}catch (Exception ex){WriteLog(filePath, "计时器错误: " + ex.Message);throw;}}//执行的操作private void Execute(object sender, ElapsedEventArgs e){//注册SAP客户端this.RegisterDestination();//获取当前的每日定时开关状态dayScheduleSwitch = Convert.ToBoolean(ConfigurationManager.AppSettings["DayScheduleSwitch"]);//获取每日定时执行的时间dayScheduleTime = ConfigurationManager.AppSettings["DayScheduleTime"];//获取当时的每月定时开关状态monthScheduleSwitch = Convert.ToBoolean(ConfigurationManager.AppSettings["MonthScheduleSwitch"]);//如果每日定时开关打开,并且当时是设置的时间if (dayScheduleSwitch && DateTime.Now.ToString("t") == dayScheduleTime){timer.Stop();//获取SAP数据this.InvokeRFCFunctionGetJobList();WriteLog(filePath, "第 " + n + " 次数据写入完毕------");n++;timer.Start();}else if (monthScheduleSwitch) //每月定时开关是打开状态{DateTime dt = DateTime.Now;int year = dt.Date.Year;    //获取当前的年int month = dt.Date.Month;  //获取当前的月int dayCount = DateTime.DaysInMonth(year, month); //返回这个当前年当前月的天数var endDayOfMonth = new DateTime(year, month, dayCount, 0, 0, 0);  //最后一天if (DateTime.Now.ToString("g") == endDayOfMonth.ToString("g"))//g:常规(短日期和短时间){timer.Stop();//获取SAP数据this.InvokeRFCFunctionGetJobList();WriteLog(filePath, "第 " + n + " 次数据写入完毕------");n++;timer.Start();}}//DateTime dt = DateTime.Now;//int year = dt.Date.Year;    //获取当前的年//int month = dt.Date.Month;  //获取当前的月//int dayCount = DateTime.DaysInMonth(year, month); //返回这个当前年当前月的天数//var endDayOfMonth = new DateTime(year, month, dayCount, 0, 0, 0);  //最后一天if (DateTime.Now.ToString("t") == "7:00" || DateTime.Now.ToString("t") == "11:30" || DateTime.Now.ToString("t") == "18:00")if (DateTime.Now.ToString("g") == endDayOfMonth.ToString("g"))//g:常规(短日期和短时间)//if (DateTime.Now.ToString("t") == "16:30")//{//    timer.Stop();//    //获取SAP数据//    this.InvokeRFCFunctionGetJobList();//    WriteLog(filePath, "第 " + n + " 次数据写入完毕------");//    n++;//    timer.Start();//}}//获取函数private void InvokeRFCFunctionGetJobList(){//数据表DataTable dataTable = new DataTable();//根据Destination获取函数IRfcFunction rfcFunction = null;try{WriteLog(filePath, "获取数据,第 "+ n +" 次------");RfcRepository rfcRepository = _rfcDestination.Repository;rfcFunction = rfcRepository.CreateFunction("Z_TEST_CSHAP_GET_MARA");rfcFunction.SetValue("I_MATKL", "10010101");  //设置参数rfcFunction.SetParameterActive(0, false); //设置参数有效性,false无效rfcFunction.Invoke(_rfcDestination);     //执行函数IRfcTable rfcTable = rfcFunction.GetTable("OT_TABLE"); //获取返回的表//给数据表添加列结构for (int i = 0; i < rfcTable.ElementCount; i++){RfcElementMetadata rfcElementMetadata = rfcTable.GetElementMetadata(i);dataTable.Columns.Add(rfcElementMetadata.Name);}//填充数据表DataRow drH = dataTable.NewRow();drH["MATNR"] = "物料编号";drH["MAKTX"] = "物料描述";drH["ERSDA"] = "创建日期";drH["MATKL"] = "物料组";drH["MEINS"] = "基本计量单位";drH["ZGUIG"] = "规格";dataTable.Rows.Add(drH);//填充数据foreach (IRfcStructure rs in rfcTable){DataRow dr = dataTable.NewRow();//循环每一列for (int i = 0; i < rfcTable.ElementCount; i++){RfcElementMetadata rfcElement = rfcTable.GetElementMetadata(i);dr[rfcElement.Name] = rs.GetString(rfcElement.Name);}dataTable.Rows.Add(dr);}dataTable.TableName = "Data";//复制模板Excel,覆盖原来的旧的Excel文件File.Copy(excelFileTemplatePath, excelFilePath, true);//选择解析文档格式相匹配的字符串string connectString = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + excelFilePath + ";" + ";Extended Properties='Excel 12.0;HDR=YES;IMEX=0'";using(OleDbConnection con = new OleDbConnection(connectString)){con.Open();string insertCmd = "INSERT INTO [Sheet1$] (物料编号,物料描述,创建日期,物料组,基本计量单位,规格) VALUES (?, ?, ?, ?, ?, ?)";//拼接插入语句;//创建执行命令OleDbCommand command = new OleDbCommand(insertCmd, con);//定义执行命令对应值的参数类型;command.Parameters.Add("@物料编号", OleDbType.VarChar);command.Parameters.Add("@物料描述", OleDbType.VarChar);command.Parameters.Add("@创建日期", OleDbType.DBDate);command.Parameters.Add("@物料组", OleDbType.VarChar);command.Parameters.Add("@基本计量单位", OleDbType.VarChar);command.Parameters.Add("@规格", OleDbType.VarChar);//执行插入语句for (int i = 1; i < dataTable.Rows.Count; i++){command.Parameters["@物料编号"].Value = dataTable.Rows[i]["MATNR"].ToString();command.Parameters["@物料描述"].Value = dataTable.Rows[i]["MAKTX"].ToString();command.Parameters["@创建日期"].Value = dataTable.Rows[i]["ERSDA"].ToString();command.Parameters["@物料组"].Value = dataTable.Rows[i]["MATKL"].ToString();command.Parameters["@基本计量单位"].Value = dataTable.Rows[i]["MEINS"].ToString();command.Parameters["@规格"].Value = dataTable.Rows[i]["ZGUIG"].ToString();command.ExecuteNonQuery();}con.Close();}#region 写入txt文件,已经注释写入txt文件//string dataFilePath = "D:\\Projects\\Visual_Studio_2022\\WindowsService1_SAP_RFC\\Data.txt";//using (StreamWriter sw = new StreamWriter(dataFilePath,true))//{//    foreach (IRfcStructure rs in rfcTable)//    {//        sw.Write(rs.GetString(0).Trim().ToString() + " ");//        sw.Write(rs.GetString(1).Trim().ToString() + " ");//        sw.Write(rs.GetString(2).Trim().ToString() + " ");//        sw.Write(rs.GetString(3).Trim().ToString() + " ");//        sw.Write(rs.GetString(4).Trim().ToString() + " ");//        sw.Write(rs.GetString(5).Trim().ToString() + " ");//        sw.WriteLine();//    }//}#endregion}catch (Exception ex){WriteLog(filePath, "发生错误: " + ex.Message);throw;}}private void RegisterDestination(){try{if (_rfcDestination == null){//_rfcDestination = RfcDestinationManager.GetDestination("S4P");  //正式库_rfcDestination = RfcDestinationManager.GetDestination("S4D");  //测试库}}catch (Exception ex){WriteLog(filePath, "SAP注册客户端失败: " + ex.Message);}}//写日志private void WriteLog(string filePath,string message){StreamWriter sw = null;try{//创建一个log文件sw = new StreamWriter(filePath, true);sw.WriteLine(message + DateTime.Now.ToString());}catch(Exception ex){sw.Write(ex.Message + DateTime.Now.ToString());}finally{if (sw != null){sw.Close();  //关闭流对象sw.Dispose(); //释放资源}}}//服务停止时调用protected override void OnStop(){WriteLog(filePath, "停止服务------");}}
}

配置文件

在这里插入图片描述

<?xml version="1.0" encoding="utf-8" ?>
<configuration><!--关于连接SAP的配置--><configSections><sectionGroup name="SAP.Middleware.Connector"><sectionGroup name="ClientSettings"><section name="DestinationConfiguration" type="SAP.Middleware.Connector.RfcDestinationConfiguration,sapnco"/></sectionGroup></sectionGroup></configSections><SAP.Middleware.Connector><ClientSettings><DestinationConfiguration><destinations><!--正式系统800--><!--<add NAME="S4P" USER="999999" PASSWD="Hs123456789" CLIENT="800" SYSNR="00" ASHOST="192.168.4.23" LANG="ZH" GROUP="PUBLIC" MAX_POOL_SIZE="10" IDLE_TIMEOUT="600"/>--><!--测试系统310--><add NAME="S4D" USER="024083" PASSWD="Hs87654321" CLIENT="310" SYSNR="00" ASHOST="192.168.4.20" LANG="ZH" GROUP="PUBLIC" MAX_POOL_SIZE="10" IDLE_TIMEOUT="600"/></destinations></DestinationConfiguration></ClientSettings></SAP.Middleware.Connector><startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" /></startup><startup useLegacyV2RuntimeActivationPolicy="true"><supportedRuntime version="v4.0"/></startup><!--配置日志的位置--><appSettings><!--本机测试目录--><add key="FilePath" value="D:\Projects\Visual_Studio_2022\WindowsService1_SAP_RFC\log.txt" /><add key="ExcelFilePath" value="D:\Projects\Visual_Studio_2022\WindowsService1_SAP_RFC\SAP返回数据.xlsx"/><add key="ExcelFileTemplatePath" value="D:\Projects\Visual_Studio_2022\WindowsService1_SAP_RFC\SAP返回数据模板.xlsx"/><!--服务器测试目录--><!--<add key="FilePath" value="D:\HS_C#Service_RFC_SAP_TEST\WindowsService1_SAP_RFC\log.txt" /><add key="ExcelFileTemplatePath" value="D:\HS_C#Service_RFC_SAP_TEST\WindowsService1_SAP_RFC\SAP返回数据模板.xlsx"/><add key="ExcelFilePath" value="D:\HS_C#Service_RFC_SAP_TEST\WindowsService1_SAP_RFC\SAP返回数据.xlsx"/>--><!--每月循环开关MonthScheduleSwitch,如果打开(设置为true)就是每月月末执行生成Excel,关闭(设置为false)就不执行--><add key="MonthScheduleSwitch" value="false"/><!--定时开关DayScheduleSwitch,如果打开(设置为true)就是每天定时执行生成Excel,关闭(设置为false)就不执行--><add key="DayScheduleSwitch" value="true"/><!--time:指定每天定时生成Excel的时间 9:00,10:00的格式--><add key="DayScheduleTime" value="14:30"/><add key="ClientSettingsProvider.ServiceUri" value="" /></appSettings>
</configuration>

注意!!

要先创建好Excel表,并预先准备好表头:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/501314.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OFDM学习-(二)长短序列和PPDU整体数据处理流程

OFDM学习 &#xff08;二&#xff09;长短序列和PPDU整体数据处理流程 OFDM学习前言一、短序列短序列的作用 二、长序列三、PLCP/SIGNAL/DATA数据处理流程三、fpga实现STS模块LTS模块训练序列模块仿真波形 总结 前言 根据框图可以知道发射机这部分信号在DA转换之前&#xff0c…

leetcode 173.二叉搜索树迭代器栈绝妙思路

以上算法题中一个比较好的实现思路就是利用栈来进行实现&#xff0c;以下方法三就是利用栈来进行实现的&#xff0c;思路很好&#xff0c;很简练。进行next的时候&#xff0c;先是一直拿到左边的子树&#xff0c;直到null为止&#xff0c;这一步比较好思考一点&#xff0c;下一…

商用车自动驾驶,迎来大规模量产「临界点」?

商用车自动驾驶&#xff0c;正迎来新的行业拐点。 今年初&#xff0c;交通部公开发布AEB系统运营车辆标配征求意见稿&#xff0c;首次将法规限制条件全面放开&#xff0c;有望推动商用车AEB全面标配&#xff0c;为开放场景的商用车智能驾驶市场加了一把火。 另外&#xff0c;…

kubernetes学习-kubectl命令、探针(二)

一、在任意节点使用 kubectl # 在master节点获取节点信息 [rootk8s-master k8s]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master Ready control-plane,master 16h v1.23.6 k8s-node1 Ready <none> …

关于IDE的相关知识之三【插件安装、配置及推荐的意义】

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于ide插件安装、配置及推荐意义的相关内容…

Node 如何生成 RSA 公钥私钥对

一、引入crypto模块 crypto 为node 自带模块&#xff0c;无需安装 const crypto require(crypto);二、封装生成方法 async function generateRSAKeyPair() {return new Promise((resolve, reject) > {crypto.generateKeyPair(rsa, {modulusLength: 2048, // 密钥长度为 …

数字PWM直流调速系统设计(论文+源码)

2.1 系统方案设计 2.2.1开环控制方案 采用开环方案的系统架构如图2.1所示&#xff0c;这种方式不需要对直流电机的转速进行检测&#xff0c;在速度控制时单片机只需要直接发出PWM就可以实现直流电机速度的控制。这种方式整体设计难度较低&#xff0c;但是无法准确得知当前的…

w~多模态~合集1

我自己的原文哦~ https://blog.51cto.com/whaosoft/12663226 #Vista-LLaMA Vista-LLaMA 在处理长视频内容方面的显著优势&#xff0c;为视频分析领域带来了新的解决框架。AI解读视频张口就来&#xff1f;这种「幻觉」难题给解决了 近年来&#xff0c;大型语言模型如 GPT、…

2025年第五届控制理论与应用国际会议 | Ei Scopus双检索

会议简介 Brief Introduction 2025年第五届控制理论与应用国际会议(ICoCTA 2025) 会议时间&#xff1a;2025年9月19 -21日 召开地点&#xff1a;中国成都 大会官网&#xff1a;www.icocta.org 控制理论作为一门科学技术&#xff0c;已经广泛地运用于我们社会生活方方面面。随着…

SASS 简化代码开发的基本方法

概要 本文以一个按钮开发的实例&#xff0c;介绍如何使用SASS来简化CSS代码开发的。 代码和实现 我们希望通过CSS开发下面的代码样式&#xff0c;从样式来看&#xff0c;每个按钮的基本样式相同&#xff0c;就是颜色不同。 如果按照传统的方式开发&#xff0c;需要开发btn &…

项目:停车场车辆管理系统

这个代码实现了一个停车场管理系统&#xff0c;主要功能包括车辆信息的添加、删除、修改、查找、显示所有车辆信息、排序以及计算停车费用。系统使用双向链表来存储车辆数据&#xff0c;并提供了菜单驱动的界面供用户选择不同的操作。 主要功能描述&#xff1a; 添加车辆信息&…

RS485方向自动控制电路分享

我们都知道RS485是半双工通信&#xff0c;所以在传输的时候需要有使能信号&#xff0c;标明是发送还是接收信号&#xff0c;很多时候就简单的用一个IO口控制就好了&#xff0c;但是有一些低成本紧凑型的MCU上&#xff0c;一个IO口也是很珍贵的&#xff0c;因此&#xff0c;如果…

《代码随想录》Day24打卡!

《代码随想录》回溯算法&#xff1a;复原IP地址 本题的完整题目如下&#xff1a; 本题的完整思路如下&#xff1a; 1.本题使用递归以及回溯来做&#xff0c;所以依然分为三部曲&#xff1a; 2.第一步&#xff1a;确定递归的参数和返回值&#xff1a;无返回值&#xff0c;参数为…

uboot ,s5pv210 ,bootm分析

先来看看 bootm 的逻辑。 1、 首先是 两 zimage 加上一个头, 变成 Uimage 2、然后是将 uimage 烧写到 TF 卡上去。 3、 然后是 TF 卡上的 uimgae 拷贝到 内存的一段位置上。 4、 然后就是 跳转到 内存的 这个位置上 去运行代码了。 uboot中 将 zimage 变成 uimage…

JS基础 -- 数组 (对象 / 数组 / 类数组 / 对象数组)的遍历

一、数组&#xff1a; 数组是复杂数据类型&#xff0c;用于存储一组有序的数据。 1、创建数组&#xff1a; ① 使用 new 关键字&#xff1a; let arr new Array() // 创建一个长度为0的空数组 let arrLength new Array(5) // 创建一个长度为5的空数组② 字面量形式&#…

利用 AI 高效生成思维导图的简单实用方法

#工作记录 适用于不支持直接生成思维导图的AI工具&#xff1b;适用于AI生成后不能再次编辑的思维导图。 在日常的学习、工作以及知识整理过程中&#xff0c;思维导图是一种非常实用的工具&#xff0c;能够帮助我们清晰地梳理思路、归纳要点。而借助 AI 的强大能力&#xff0c…

嵌入式学习(21)-正点原子脱机下载器Mini-Pro的使用

一、概述 通过脱机下载器可以脱离电脑给电路板下载程序&#xff0c;方便在产线上给PCB烧录程序。 二、程序烧录到脱机下载器 1、驱动及软件下载&#xff1a; https://download.csdn.net/download/A18763139629/90215719 2、软件安装 3、烧录程序 通过USB线与脱机下载器连…

二维码文件在线管理系统-收费版

需求背景 如果大家想要在网上管理自己的文件&#xff0c;而且需要生成二维码&#xff0c;下面推荐【草料二维码】&#xff0c;这个系统很好。特别适合那些制造业&#xff0c;实体业的使用手册&#xff0c;你可以生成一个二维码&#xff0c;贴在设备上&#xff0c;然后这个二维码…

【C语言程序设计——循环程序设计】枚举法换硬币(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 一、循环控制 / 跳转语句的使用 1. 循环控制语句&#xff08;for 循环&#xff09; 2. 循环控制语句&#xff08;while 循环&#xff09; 3. 跳转语句&#xff08;break 语句&#xff09; 4. 跳转语句&#xff08;continue 语句&…

【Multisim用74ls92和90做六十进制】2022-6-12

缘由Multisim如何用74ls92和90做六十进制-其他-CSDN问答 74LS92、74LS90参考