适用于 Microsoft .Net v3 的 SAP 连接器 - 缺少 SAPIDocSender class
SAP Connector for Microsoft .Net v3 - SAPIDocSender class missing
我已经使用 SAP Connector for Microsoft .Net v2 成功地将已经格式化的 IDOCS 发送到 SAP。
今天我升级到最新版本的连接器。
不幸的是,这个 SAPIDocSender 已经不存在了。
我现在应该如何将这些 IDOCS 发送到 SAP?
感谢您的帮助!
编辑:
谢谢!
不幸的是,我想像其他线程中描述的那样构建 IDOC。
在 v2 中,有一个选项可以发送包括所有段在内的整个 IDOC 字符串:
private static void SendIdoc()
{
SAP.Connector.RfcTID myTid = SAP.Connector.RfcTID.NewTID();
string connectionString = "ASHOST=xxxx SYSNR=xx CLIENT=xxx USER=xxx PASSWD=xxx LANG=xx";
string upperString = connectionString.ToUpper();
SAP.Connector.SAPIDocSender sapiDocSender = new SAPIDocSender(upperString);
sapiDocSender.SubmitIDoc(@"C:\Users\xxx\Documents\testidoc.txt", myTid);
sapiDocSender.ConfirmTID(myTid);
}
据我所知,当前的 Net Connector 3 中现在有 idoc 助手。但是如果您有一个包含有效 idoc 的文件,那么您已经拥有了所需的所有信息。
关于将 Idoc 发送到 SAP 系统的基础知识已经描述 here,所以我不会在这个答案中详细介绍。要发送您的 idoc 文件,您必须手动填写控制记录(您的 idoc 的第一行)和数据记录。
控件 table 需要一些体力劳动。幸运的是,控制记录在所有 idoc 上都是相同的,因此您不必考虑发送的 idoc 类型。
var fileStream = System.IO.File.OpenRead(fullFilepath);
var streamReader = new System.IO.StreamReader(fileStream);
string control = streamReader.ReadLine();
controlTable.Append();
controlTable.CurrentRow.SetValue("TABNAM", control.Substring(0, 10));
controlTable.CurrentRow.SetValue("MANDT", control.Substring(10, 3));
controlTable.CurrentRow.SetValue("DOCNUM", control.Substring(13, 16));
controlTable.CurrentRow.SetValue("DOCREL", control.Substring(29, 4));
controlTable.CurrentRow.SetValue("STATUS", control.Substring(33, 2));
controlTable.CurrentRow.SetValue("DIRECT", control.Substring(35, 1));
controlTable.CurrentRow.SetValue("OUTMOD", control.Substring(36, 1));
controlTable.CurrentRow.SetValue("EXPRSS", control.Substring(37, 1));
controlTable.CurrentRow.SetValue("TEST", control.Substring(38, 1));
controlTable.CurrentRow.SetValue("IDOCTYP", control.Substring(39, 30));
controlTable.CurrentRow.SetValue("CIMTYP", control.Substring(69, 30));
controlTable.CurrentRow.SetValue("MESTYP", control.Substring(99, 30));
controlTable.CurrentRow.SetValue("MESCOD", control.Substring(129, 3));
controlTable.CurrentRow.SetValue("MESFCT", control.Substring(132, 3));
controlTable.CurrentRow.SetValue("STD", control.Substring(135, 1));
controlTable.CurrentRow.SetValue("STDVRS", control.Substring(136, 6));
controlTable.CurrentRow.SetValue("STDMES", control.Substring(142, 6));
controlTable.CurrentRow.SetValue("SNDPOR", control.Substring(148, 10));
controlTable.CurrentRow.SetValue("SNDPRT", control.Substring(158, 2));
controlTable.CurrentRow.SetValue("SNDPFC", control.Substring(160, 2));
controlTable.CurrentRow.SetValue("SNDPRN", control.Substring(162, 10));
controlTable.CurrentRow.SetValue("SNDSAD", control.Substring(172, 21));
controlTable.CurrentRow.SetValue("SNDLAD", control.Substring(193, 70));
controlTable.CurrentRow.SetValue("RCVPOR", control.Substring(263, 10));
controlTable.CurrentRow.SetValue("RCVPRT", control.Substring(273, 2));
controlTable.CurrentRow.SetValue("RCVPFC", control.Substring(275, 2));
controlTable.CurrentRow.SetValue("RCVPRN", control.Substring(277, 10));
controlTable.CurrentRow.SetValue("RCVSAD", control.Substring(287, 21));
controlTable.CurrentRow.SetValue("RCVLAD", control.Substring(308, 70));
controlTable.CurrentRow.SetValue("REFMES", control.Substring(420, 14));
var dataLine = streamReader.ReadLine();
while (dataLine != null) {
dataTable.Append();
dataTable.CurrentRow.SetValue("SEGNAM", dataLine.SubString(0, 30));
dataTable.CurrentRow.SetValue("MANDT", dataLine.SubString(30, 3));
dataTable.CurrentRow.SetValue("DOCNUM", dataLine.SubString(33, 16));
dataTable.CurrentRow.SetValue("SEGNUM", dataLine.SubString(49, 6));
dataTable.CurrentRow.SetValue("PSGNUM", dataLine.SubString(55, 6));
dataTable.CurrentRow.SetValue("HLEVEL", dataLine.SubString(61, 2));
dataTable.CurrentRow.SetValue("SDATA", dataLine.SubString(63, dataLine.Length - 63));
dataLine = streamReader.ReadLine();
}
此代码段需要文件中的单个 idoc。如果一个文件中有多个idoc,则需要通过查找控制记录来拆分它们(控制记录行通常以"EDI_DC40"开头)。
根据德克的回答,我刚刚创建了 2 种方法来使用可用的元数据动态填充控件和数据表:
private static void AddControlToIdocTable(ref IRfcTable control, string controlLine)
{
var lineType = control.Metadata.LineType;
//Append a new Control Row
control.Append();
//Creates an empty array with the Count of the different fields the RfcTable consists of
string[] columns = new string[control.Metadata.LineType.FieldCount];
for (int i = 0; i < columns.Length; i++)
{
//Get the Type containg the structure of the field
var type = lineType[i];
//If NucOffset + NucLength is not bigger then the length of the current control line
//we append the substring of the control line using those values (Offset + Length)
if(controlLine.Length >= (type.NucOffset + type.NucLength))
control.CurrentRow.SetValue(type.Name, controlLine.Substring(type.NucOffset, type.NucLength));
}
}
private static void AddDataToIdocTable(ref IRfcTable records, List<string> dataLines)
{
var lineType = records.Metadata.LineType;
//Creates an empty array with the Count of the different fields the RfcTable consists of
string[] columns = new string[records.Metadata.LineType.FieldCount];
foreach (string dataLine in dataLines)
{
//Append a new Data Row for every data line
records.Append();
for (int i = 0; i < columns.Length; i++)
{
//Get the Type containg the structure of the field
var type = lineType[i];
//If NucOffset + NucLength is not bigger then the length of the current control line
//we append the substring of the control line using those values (Offset + Length)
if (dataLine.Length >= (type.NucOffset + type.NucLength))
records.CurrentRow.SetValue(type.Name, dataLine.Substring(type.NucOffset, type.NucLength));
}
}
}
测试后会post一些进一步的细节。谢谢!
我使用 Fabio 的代码工作了几分钟,并阅读了 SAP 文档,并想出了这种填充表的方法。 (控制表和数据表是一样的class)
private void AppendRecordToTable(IRfcTable idocTable, string textRecord)
{
var structure = idocTable.Metadata.LineType.CreateStructure();
foreach (var field in structure)
{
var fieldMeta = field.Metadata;
var fieldValue = CreateFieldValue(fieldMeta, textRecord);
structure.SetValue(fieldMeta.Name, fieldValue);
}
idocTable.Append(structure);
}
private string CreateFieldValue(RfcFieldMetadata fieldMeta, string record)
{
if (record.Length < fieldMeta.NucOffset)
return new string(' ', fieldMeta.NucLength);
if (record.Length < fieldMeta.NucOffset + fieldMeta.NucLength)
return record.Substring(fieldMeta.NucOffset).PadRight(fieldMeta.NucLength);
return record.Substring(fieldMeta.NucOffset, fieldMeta.NucLength);
}
我已经使用 SAP Connector for Microsoft .Net v2 成功地将已经格式化的 IDOCS 发送到 SAP。 今天我升级到最新版本的连接器。 不幸的是,这个 SAPIDocSender 已经不存在了。 我现在应该如何将这些 IDOCS 发送到 SAP?
感谢您的帮助!
编辑: 谢谢! 不幸的是,我想像其他线程中描述的那样构建 IDOC。
在 v2 中,有一个选项可以发送包括所有段在内的整个 IDOC 字符串:
private static void SendIdoc()
{
SAP.Connector.RfcTID myTid = SAP.Connector.RfcTID.NewTID();
string connectionString = "ASHOST=xxxx SYSNR=xx CLIENT=xxx USER=xxx PASSWD=xxx LANG=xx";
string upperString = connectionString.ToUpper();
SAP.Connector.SAPIDocSender sapiDocSender = new SAPIDocSender(upperString);
sapiDocSender.SubmitIDoc(@"C:\Users\xxx\Documents\testidoc.txt", myTid);
sapiDocSender.ConfirmTID(myTid);
}
据我所知,当前的 Net Connector 3 中现在有 idoc 助手。但是如果您有一个包含有效 idoc 的文件,那么您已经拥有了所需的所有信息。
关于将 Idoc 发送到 SAP 系统的基础知识已经描述 here,所以我不会在这个答案中详细介绍。要发送您的 idoc 文件,您必须手动填写控制记录(您的 idoc 的第一行)和数据记录。
控件 table 需要一些体力劳动。幸运的是,控制记录在所有 idoc 上都是相同的,因此您不必考虑发送的 idoc 类型。
var fileStream = System.IO.File.OpenRead(fullFilepath);
var streamReader = new System.IO.StreamReader(fileStream);
string control = streamReader.ReadLine();
controlTable.Append();
controlTable.CurrentRow.SetValue("TABNAM", control.Substring(0, 10));
controlTable.CurrentRow.SetValue("MANDT", control.Substring(10, 3));
controlTable.CurrentRow.SetValue("DOCNUM", control.Substring(13, 16));
controlTable.CurrentRow.SetValue("DOCREL", control.Substring(29, 4));
controlTable.CurrentRow.SetValue("STATUS", control.Substring(33, 2));
controlTable.CurrentRow.SetValue("DIRECT", control.Substring(35, 1));
controlTable.CurrentRow.SetValue("OUTMOD", control.Substring(36, 1));
controlTable.CurrentRow.SetValue("EXPRSS", control.Substring(37, 1));
controlTable.CurrentRow.SetValue("TEST", control.Substring(38, 1));
controlTable.CurrentRow.SetValue("IDOCTYP", control.Substring(39, 30));
controlTable.CurrentRow.SetValue("CIMTYP", control.Substring(69, 30));
controlTable.CurrentRow.SetValue("MESTYP", control.Substring(99, 30));
controlTable.CurrentRow.SetValue("MESCOD", control.Substring(129, 3));
controlTable.CurrentRow.SetValue("MESFCT", control.Substring(132, 3));
controlTable.CurrentRow.SetValue("STD", control.Substring(135, 1));
controlTable.CurrentRow.SetValue("STDVRS", control.Substring(136, 6));
controlTable.CurrentRow.SetValue("STDMES", control.Substring(142, 6));
controlTable.CurrentRow.SetValue("SNDPOR", control.Substring(148, 10));
controlTable.CurrentRow.SetValue("SNDPRT", control.Substring(158, 2));
controlTable.CurrentRow.SetValue("SNDPFC", control.Substring(160, 2));
controlTable.CurrentRow.SetValue("SNDPRN", control.Substring(162, 10));
controlTable.CurrentRow.SetValue("SNDSAD", control.Substring(172, 21));
controlTable.CurrentRow.SetValue("SNDLAD", control.Substring(193, 70));
controlTable.CurrentRow.SetValue("RCVPOR", control.Substring(263, 10));
controlTable.CurrentRow.SetValue("RCVPRT", control.Substring(273, 2));
controlTable.CurrentRow.SetValue("RCVPFC", control.Substring(275, 2));
controlTable.CurrentRow.SetValue("RCVPRN", control.Substring(277, 10));
controlTable.CurrentRow.SetValue("RCVSAD", control.Substring(287, 21));
controlTable.CurrentRow.SetValue("RCVLAD", control.Substring(308, 70));
controlTable.CurrentRow.SetValue("REFMES", control.Substring(420, 14));
var dataLine = streamReader.ReadLine();
while (dataLine != null) {
dataTable.Append();
dataTable.CurrentRow.SetValue("SEGNAM", dataLine.SubString(0, 30));
dataTable.CurrentRow.SetValue("MANDT", dataLine.SubString(30, 3));
dataTable.CurrentRow.SetValue("DOCNUM", dataLine.SubString(33, 16));
dataTable.CurrentRow.SetValue("SEGNUM", dataLine.SubString(49, 6));
dataTable.CurrentRow.SetValue("PSGNUM", dataLine.SubString(55, 6));
dataTable.CurrentRow.SetValue("HLEVEL", dataLine.SubString(61, 2));
dataTable.CurrentRow.SetValue("SDATA", dataLine.SubString(63, dataLine.Length - 63));
dataLine = streamReader.ReadLine();
}
此代码段需要文件中的单个 idoc。如果一个文件中有多个idoc,则需要通过查找控制记录来拆分它们(控制记录行通常以"EDI_DC40"开头)。
根据德克的回答,我刚刚创建了 2 种方法来使用可用的元数据动态填充控件和数据表:
private static void AddControlToIdocTable(ref IRfcTable control, string controlLine)
{
var lineType = control.Metadata.LineType;
//Append a new Control Row
control.Append();
//Creates an empty array with the Count of the different fields the RfcTable consists of
string[] columns = new string[control.Metadata.LineType.FieldCount];
for (int i = 0; i < columns.Length; i++)
{
//Get the Type containg the structure of the field
var type = lineType[i];
//If NucOffset + NucLength is not bigger then the length of the current control line
//we append the substring of the control line using those values (Offset + Length)
if(controlLine.Length >= (type.NucOffset + type.NucLength))
control.CurrentRow.SetValue(type.Name, controlLine.Substring(type.NucOffset, type.NucLength));
}
}
private static void AddDataToIdocTable(ref IRfcTable records, List<string> dataLines)
{
var lineType = records.Metadata.LineType;
//Creates an empty array with the Count of the different fields the RfcTable consists of
string[] columns = new string[records.Metadata.LineType.FieldCount];
foreach (string dataLine in dataLines)
{
//Append a new Data Row for every data line
records.Append();
for (int i = 0; i < columns.Length; i++)
{
//Get the Type containg the structure of the field
var type = lineType[i];
//If NucOffset + NucLength is not bigger then the length of the current control line
//we append the substring of the control line using those values (Offset + Length)
if (dataLine.Length >= (type.NucOffset + type.NucLength))
records.CurrentRow.SetValue(type.Name, dataLine.Substring(type.NucOffset, type.NucLength));
}
}
}
测试后会post一些进一步的细节。谢谢!
我使用 Fabio 的代码工作了几分钟,并阅读了 SAP 文档,并想出了这种填充表的方法。 (控制表和数据表是一样的class)
private void AppendRecordToTable(IRfcTable idocTable, string textRecord)
{
var structure = idocTable.Metadata.LineType.CreateStructure();
foreach (var field in structure)
{
var fieldMeta = field.Metadata;
var fieldValue = CreateFieldValue(fieldMeta, textRecord);
structure.SetValue(fieldMeta.Name, fieldValue);
}
idocTable.Append(structure);
}
private string CreateFieldValue(RfcFieldMetadata fieldMeta, string record)
{
if (record.Length < fieldMeta.NucOffset)
return new string(' ', fieldMeta.NucLength);
if (record.Length < fieldMeta.NucOffset + fieldMeta.NucLength)
return record.Substring(fieldMeta.NucOffset).PadRight(fieldMeta.NucLength);
return record.Substring(fieldMeta.NucOffset, fieldMeta.NucLength);
}