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

news2025/1/6 2:56:48

这个例子是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分钟

                //时间间隔到了之后,执行的操作为Execute
                timer.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.coloradmin.cn/o/2270667.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

戴尔/Dell 电脑按什么快捷键可以进入 Bios 设置界面?

BIOS&#xff08;基本输入输出系统&#xff09;是计算机硬件与操作系统之间的桥梁&#xff0c;它负责初始化和测试系统硬件组件&#xff0c;并加载启动操作系统。在某些情况下&#xff0c;如调整启动顺序、更改系统时间或日期、修改硬件配置等&#xff0c;您可能需要进入BIOS进…

利用3DGS中convert.py处理自采数据

前言 3DGS源码中convert.py提供对自采数据集的处理&#xff0c;需要预先安装Colmap和ImageMagick. ubuntu22.04安装colmap 点击进入NVIDIA官网&#xff0c;查看GPU的CMAKE_CUDA_ARCHITECTURES 1、克隆colmap源码&#xff0c;并进入colmap文件夹 git clone https://github.c…

数据结构(ing)

学习内容 指针 指针的定义&#xff1a; 指针是一种变量&#xff0c;它的值为另一个变量的地址&#xff0c;即内存地址。 指针在内存中也是要占据位置的。 指针类型&#xff1a; 指针的值用来存储内存地址&#xff0c;指针的类型表示该地址所指向的数据类型并告诉编译器如何解…

实践:事件循环

实践&#xff1a;事件循环 代码示例 console.log(1); setTimeout(() > console.log(2), 0); Promise.resolve(3).then(res > console.log(res)); console.log(4);上述的代码的输出结果是什么 1和4肯定优先输出&#xff0c;因为他们会立即方式堆栈的执行上下文中执行&am…

从零开始开发纯血鸿蒙应用之逻辑封装

从零开始开发纯血鸿蒙应用 一、前言二、逻辑封装的原则三、实现 FileUtil1、统一的存放位置2、文件的增删改查2.1、文件创建与文件保存2.2、文件读取2.2.1、读取内部文件2.2.2、读取外部文件 3、文件删除 四、总结 一、前言 应用的动态&#xff0c;借助 UI 响应完成&#xff0…

ESP32 I2S音频总线学习笔记(一):初识I2S通信与配置基础

文章目录 简介为什么需要I2S&#xff1f;关于音频信号采样率分辨率音频声道 怎样使用I2S传输音频&#xff1f;位时钟BCLK字时钟WS串行数据SD I2S传输模型I2S通信格式I2S格式左对齐格式右对齐格式 i2s基本配置i2s 底层API加载I2S驱动设置I2S使用的引脚I2S读取数据I2S发送数据卸载…

CSS 中 content换行符实现打点 loading 正在加载中的效果

我们动态加载页面内容的时候&#xff0c;经常会使用“正在加载中…”这几个字&#xff0c;基本上&#xff0c;后面的 3 个点都是静态的。静态的问题在于&#xff0c;如果网络不流畅&#xff0c;加载时间比较长&#xff0c;就会给人有假死的 感觉&#xff0c;但是&#xff0c;如…

25考研王道数据结构课后习题笔记

声明&#xff1a;以下内容来自于B栈知名up主–白话拆解数据结构 回答&#xff1a;为什么要做这个&#xff0c;因为我这个学期学完了数据结构&#xff0c;而且这个数据结构是408的重头&#xff0c;为什么选择25的&#xff0c;因为这个25考研刚刚结束&#xff0c;25相对成熟&…

小程序发版后,强制更新为最新版本

为什么要强制更新为最新版本&#xff1f; 在小程序的开发和运营过程中&#xff0c;强制用户更新到最新版本是一项重要的策略&#xff0c;能够有效提升用户体验并保障系统的稳定性与安全性。以下是一些主要原因&#xff1a; 1. 功能兼容 新功能或服务通常需要最新版本的支持&…

GRAPE——RLAIF微调VLA模型:通过偏好对齐提升机器人策略的泛化能力(含24年具身模型汇总)

前言 24年具身前沿模型大汇总 过去的这两年&#xff0c;工作之余&#xff0c;我狂写大模型与具身的文章&#xff0c;加之具身大火&#xff0c;每周都有各种朋友通过CSDN私我及我司「七月在线」寻求帮助/指导(当然&#xff0c;也欢迎各大开发团队与我司合作共同交付&#xff09…

0xc0000020错误代码怎么处理,Windows11、10坏图像错误0xc0000020的修复办法

“0xc0000020”是一种 Windows 应用程序错误代码&#xff0c;通常表明某些文件缺失或损坏。这可能是由于系统文件损坏、应用程序安装或卸载问题、恶意软件感染、有问题的 Windows 更新等原因导致的。 比如&#xff0c;当运行软件时&#xff0c;可能会出现类似“C:\xx\xxx.dll …

pycharm+anaconda创建项目

pycharmanaconda创建项目 安装&#xff1a; Windows下PythonPyCharm的安装步骤及PyCharm的使用-CSDN博客 详细Anaconda安装配置环境创建教程-CSDN博客 创建项目&#xff1a; 开始尝试新建一个项目吧&#xff01; 选择好项目建设的文件夹 我的项目命名为&#xff1a;pyth…

基于Pytorch和yolov8n手搓安全帽目标检测的全过程

一.背景 还是之前的主题&#xff0c;使用开源软件为公司搭建安全管理平台&#xff0c;从视觉模型识别安全帽开始。主要参考学习了开源项目 https://github.com/jomarkow/Safety-Helmet-Detection&#xff0c;我是从运行、训练、标注倒过来学习的。由于工作原因&#xff0c;抽空…

【PDF物流单据提取明细】批量PDF提取多个区域内容导出表格或用区域内容对文件改名,批量提取PDF物流单据单号及明细导出表格并改名的技术难点及小节

相关阅读及下载&#xff1a; PDF电子物流单据&#xff1a; 批量PDF提取多个区域局部内容重命名PDF或者将PDF多个局部内容导出表格&#xff0c;具体使用步骤教程和实际应用场景的说明演示https://mp.weixin.qq.com/s/uCvqHAzKglfr40YPO_SyNg?token720634989&langzh_CN扫描…

JavaWeb开发(五)Servlet-ServletContext

1. ServletContext 1.1. ServletContext简介 1.1.1. ServletContext定义 ServletContext即Servlet上下文对象&#xff0c;该对象表示当前的web应用环境信息。 1.1.2. 获取ServletContext对象: &#xff08;1&#xff09;通过ServletConfig的getServletContext()方法可以得到…

长时间序列预测算法---Informer

目录 一、传统的 Transformer 模型二、Informer原理2.1 Attention计算2.2 “积极”的Q筛选2.2.1 KL散度2.2.2 “懒惰”的q处理 2.3 Encoder结构2.4 Decoder结构2.4.1 Transformer的Decoder操作2.4.2 Informer的Decoder操作 2.5 Informer模型的改进 三、模型应用 时间序列相关参…

点击取消按钮,console出来数据更改了,页面视图没有更新

点击取消按钮&#xff0c;console出来数据更改了&#xff0c;页面视图没有更新 前言 实现效果&#xff1a;点击取消按钮&#xff0c;页面视图全部为空&#xff0c; 遇到的问题&#xff1a; 点击取消按钮&#xff0c;console出来数据更改了&#xff0c;SchemaJson 都是默认值啦…

RFID手持机与RFID工业平板在仓储物流管理系统中的选型

概述 随着物联网技术在仓储物流管理系统中的普及&#xff0c;RFID手持机与RFID工业平板作为基于RFID技术手持式读写器的两种重要终端设备形态&#xff0c;得到了广泛应用。尽管RFID手持机与RFID工业平板都具备读写 RFID标签的基本功能&#xff0c;使用场景较为类似&#xff0c…

UML之泛化、特化和继承

在UML&#xff08;统一建模语言&#xff09;中&#xff0c;泛化&#xff08;Generalization&#xff09;和特化&#xff08;Specialization&#xff09;是面向对象思想中继承&#xff08;Inheritance&#xff09;关系的重要概念&#xff0c;它们描述类与类&#xff08;或用例与…

vue 修改vant样式NoticeBar中的图标,不用插槽可以直接用图片

使用文档中是可以直接使用图片链接的 :left-icon"require(../../assets/newImages/noticeImg.png)" <html> .... <NoticeBarmode""color"#C6C6C6"background""v-if"global_info.site_bulletin":left-icon"r…