测试环境

新安装的u813.0虚拟机演示帐套,替换了login,mssql2012,vs2017

引用dll

  1. 接下来会手把手教你完成单据审核、加载、弃审、删除、新增
  2. C:\U8SOFT\U8KCSN\bin目录下引用下面的dll

image.png

  1. adodb.dll可以在vs中找到,这里也提供文件

adodb.zip
image.png

vs会提示
image.png

其他入库单

  1. 在u8上新建一张其他入库单如下,后面加载、审核、弃审、删除使用

image.png

加载单据

  1. GetU8Login获取u8登陆对象
  2. USERPCO.VoucherCO.Load方法用于加载单据,08是其他入库单,这里加载id为1000000015的单据
    1. private void button2_Click(object sender, EventArgs e)
    2. {
    3. U8Login.clsLogin u8login = GetU8Login();
    4. string Msg = "";
    5. var VCO = new USERPCO.VoucherCO();
    6. VCO.IniLogin(u8login, ref Msg);
    7. if (!string.IsNullOrEmpty(Msg))
    8. {
    9. throw new Exception(Msg);
    10. }
    11. MSXML2.IXMLDOMDocument2 domHead = new MSXML2.DOMDocumentClass();
    12. MSXML2.IXMLDOMDocument2 domBody = new MSXML2.DOMDocumentClass();
    13. MSXML2.IXMLDOMDocument2 domPos = new MSXML2.DOMDocumentClass();
    14. bool bb = VCO.Load("08", "ID='1000000015'", ref domHead, ref domBody, ref domPos, ref Msg, false, "");
    15. string xml = domHead.xml;
    16. xml = domBody.xml;
    17. xml = domPos.xml;
    18. u8login.ShutDown();
    19. }

image.png

审核单据

  1. USERPCO.VoucherCO.Verify 审核刚刚创建的其他入库单

    1. private void button3_Click(object sender, EventArgs e)
    2. {
    3. ADODB.Connection con = null;
    4. try
    5. {
    6. U8Login.clsLogin u8login = GetU8Login();
    7. string VouchId = "1000000015";
    8. string Msg = "";
    9. con = new ADODB.Connection();
    10. con.ConnectionString = u8login.UfDbName;
    11. con.Open();
    12. con.BeginTrans();
    13. USERPCO.VoucherCO VCO = new USERPCO.VoucherCO();
    14. VCO.IniLogin(u8login, ref Msg);
    15. if (!string.IsNullOrEmpty(Msg))
    16. {
    17. throw new Exception(Msg);
    18. }
    19. object TimeStamp = null;
    20. MSXML2.IXMLDOMDocument2 domMsg = new MSXML2.DOMDocumentClass();
    21. bool bCheck = true, bBeforCheckStock = true, bList = false;
    22. bool bsuccess = VCO.Verify("08", VouchId, ref Msg, ref con, ref TimeStamp, ref domMsg, ref bCheck, ref bBeforCheckStock, ref bList);
    23. string errxml = domMsg.xml;
    24. if (!string.IsNullOrEmpty(Msg))
    25. {
    26. throw new Exception(Msg);
    27. }
    28. con.CommitTrans();
    29. u8login.ShutDown();
    30. }
    31. catch (Exception ex)
    32. {
    33. con.RollbackTrans();
    34. MessageBox.Show(ex.Message);
    35. }
    36. finally
    37. {
    38. con.Close();
    39. }
    40. }

弃审单据

  1. USERPCO.VoucherCO.UnVerify来弃审单据
  2. TimeStamp 为单据时间戳,可以根据此字段判断单据是否被其他人修改,弃审&删除都需要传入单据时间戳,获取方法如下,不要删除ufts前面空字符,否则会提示:该单据OI202209180001已经被其他人修改,请刷新后重新弃审
  3. 审核弃审后可查询现存量表CurrentStock看下库存

    1. select convert(nchar,convert(money,ufts),2) as ufts
    2. from rdrecord08 where ccode='OI202209180001'
    1. private void button4_Click(object sender, EventArgs e)
    2. {
    3. ADODB.Connection con = null;
    4. try
    5. {
    6. U8Login.clsLogin u8login = GetU8Login();
    7. string VouchId = "1000000015";
    8. string Msg = "";
    9. con = new ADODB.Connection();
    10. con.ConnectionString = u8login.UfDbName;
    11. con.Open();
    12. con.BeginTrans();
    13. USERPCO.VoucherCO VCO = new USERPCO.VoucherCO();
    14. VCO.IniLogin(u8login, ref Msg);
    15. if (!string.IsNullOrEmpty(Msg))
    16. {
    17. throw new Exception(Msg);
    18. }
    19. //传入时间戳
    20. object TimeStamp = " 480.8518";
    21. MSXML2.IXMLDOMDocument2 domMsg = new MSXML2.DOMDocumentClass();
    22. bool bCheck = true, bBeforCheckStock = true, bList = false;
    23. bool bsuccess = VCO.UnVerify("08", VouchId, ref Msg, ref con, ref TimeStamp, ref domMsg, ref bCheck, ref bBeforCheckStock, ref bList);
    24. string errxml = domMsg.xml;
    25. if (!string.IsNullOrEmpty(Msg))
    26. {
    27. throw new Exception(Msg);
    28. }
    29. con.CommitTrans();
    30. u8login.ShutDown();
    31. }
    32. catch (Exception ex)
    33. {
    34. con.RollbackTrans();
    35. MessageBox.Show(ex.Message);
    36. }
    37. finally
    38. {
    39. con.Close();
    40. }
    41. }

删除单据

  1. USERPCO.VoucherCO.Delete删除单据
  2. 单据需弃审才能删除,否则返回Msg:该单据OI202209180001已经被其他人修改,请刷新后重新删除

    1. private void button5_Click(object sender, EventArgs e)
    2. {
    3. ADODB.Connection con = null;
    4. try
    5. {
    6. U8Login.clsLogin u8login = GetU8Login();
    7. string VouchId = "1000000015";
    8. string Msg = "";
    9. con = new ADODB.Connection();
    10. con.ConnectionString = u8login.UfDbName;
    11. con.Open();
    12. con.BeginTrans();
    13. USERPCO.VoucherCO VCO = new USERPCO.VoucherCO();
    14. VCO.IniLogin(u8login, ref Msg);
    15. if (!string.IsNullOrEmpty(Msg))
    16. {
    17. throw new Exception(Msg);
    18. }
    19. //传入时间戳
    20. object TimeStamp = " 480.8633";
    21. MSXML2.IXMLDOMDocument2 domMsg = new MSXML2.DOMDocumentClass();
    22. bool bCheck = true, bBeforCheckStock = true, bList = false;
    23. bool bsuccess = VCO.Delete("08", VouchId, ref Msg, ref con, ref TimeStamp, ref domMsg, ref bCheck, ref bBeforCheckStock, ref bList);
    24. string errxml = domMsg.xml;
    25. if (!string.IsNullOrEmpty(Msg))
    26. {
    27. throw new Exception(Msg);
    28. }
    29. con.CommitTrans();
    30. u8login.ShutDown();
    31. }
    32. catch (Exception ex)
    33. {
    34. con.RollbackTrans();
    35. MessageBox.Show(ex.Message);
    36. }
    37. finally
    38. {
    39. con.Close();
    40. }
    41. }

到此你的winform程序应该如下
image.png

新增单据

  1. 右击引用Interop.USERPCO查看插入方法
  2. 插入方法声明如下:

sVouchType:单据类型,当前为其他入库单传08
DomHead:单据头部数据
domBody:单据体数据
domPosition:货位数据
errMsg:错误信息
[]:包裹的参数为可选参数

  1. public virtual bool Insert(string sVouchType, object DomHead, object domBody,
  2. object domPosition, ref string errMsg,
  3. [ref ADODB.Connection cnnFrom],
  4. [ref string VouchId],
  5. [ref MSXML2.IXMLDOMDocument2 domMsg],
  6. [ref bool bCheck = True],
  7. [ref bool bBeforCheckStock = True],
  8. [bool bIsRedVouch = False],
  9. [string sAddedState = ],
  10. [bool bReMote = False])

类文件

  1. 我们需要建立c#的class文件,里面的字段为其他入库单的表体表头字段

image.png

获取Dom

  1. 在加载单据接口中,你会得到单据domHead,domBody,同样的在新增时需要传入dom xml数据
  2. getDom方法将查询结果返回dom,这里用于构建一个空的dom

    1. /// <summary>
    2. /// 获取dom
    3. /// </summary>
    4. /// <param name="Strsql"></param>
    5. /// <param name="strConn"></param>
    6. /// <returns></returns>
    7. public static MSXML2.DOMDocument getDom(string Strsql, string strConn)
    8. {
    9. MSXML2.DOMDocument dom = new MSXML2.DOMDocument();
    10. ADODB.Connection conn = new ADODB.Connection();
    11. ADODB.Recordset rs = new ADODB.Recordset();
    12. conn.Open(strConn);
    13. rs.Open(Strsql, conn, ADODB.CursorTypeEnum.adOpenForwardOnly, ADODB.LockTypeEnum.adLockOptimistic, -1);
    14. rs.Save(dom, ADODB.PersistFormatEnum.adPersistXML);
    15. return dom;
    16. }
  3. 将对象数据存入dom xml ```csharp ///

    /// 获取dom /// /// /// /// public static MSXML2.DOMDocument getDom(string Strsql, string strConn) { MSXML2.DOMDocument dom = new MSXML2.DOMDocument(); ADODB.Connection conn = new ADODB.Connection(); ADODB.Recordset rs = new ADODB.Recordset(); conn.Open(strConn); rs.Open(Strsql, conn, ADODB.CursorTypeEnum.adOpenForwardOnly, ADODB.LockTypeEnum.adLockOptimistic, -1); rs.Save(dom, ADODB.PersistFormatEnum.adPersistXML); return dom; }

public static void ConvertHeadXML(MSXML2.IXMLDOMDocument2 doc, T parameter) { MSXML2.IXMLDOMNode node = doc.selectSingleNode(“//rs:data”); MSXML2.IXMLDOMElement element = doc.createElement(“z:row”); Parameter(element, parameter); node.appendChild(element); } public static void ConvertBodyXML(MSXML2.IXMLDOMDocument2 doc, List parameter) { MSXML2.IXMLDOMNode node = doc.selectSingleNode(“//rs:data”); foreach (T body in parameter) { MSXML2.IXMLDOMElement element = doc.createElement(“z:row”); Parameter(element, body); node.appendChild(element); } }

public static void Parameter(MSXML2.IXMLDOMElement element, T parameter) { object value = null; foreach (PropertyInfo pi in parameter.GetType().GetProperties()) { value = pi.GetValue(parameter, null); if (value != null && !string.IsNullOrEmpty(value.ToString())) { if (pi.PropertyType.FullName.IndexOf(“System.DateTime”) != -1) { DateTime dt = (DateTime)pi.GetValue(parameter, null); element.setAttribute( pi.Name, dt.ToString(“yyyy-MM-dd HH:mm:ss”)); } else { element.setAttribute( pi.Name, value); } }

  1. }

}

  1. <a name="uuBEW"></a>
  2. ### 执行保存
  3. 1. KCOtherInH&KCOtherInB为其他入库单视图
  4. ```csharp
  5. private void button6_Click(object sender, EventArgs e)
  6. {
  7. ADODB.Connection con = null;
  8. try
  9. {
  10. //dom
  11. MSXML2.DOMDocument domHead = new MSXML2.DOMDocument();
  12. MSXML2.DOMDocument domBody = new MSXML2.DOMDocument();
  13. MSXML2.DOMDocument domPos = new MSXML2.DOMDocument();
  14. MSXML2.IXMLDOMDocument2 domMsg = new MSXML2.DOMDocument();
  15. //登录对象
  16. U8Login.clsLogin u8login = GetU8Login();
  17. //数据库连接
  18. con = new ADODB.Connection();
  19. con.ConnectionString = u8login.UfDbName;
  20. con.Open();
  21. con.BeginTrans();
  22. //单据数据
  23. rdrecord08 head = new rdrecord08();
  24. head.cvouchtype = "08";
  25. head.cbustype = "其他入库";
  26. head.csource = "库存";
  27. head.cwhcode = "04";
  28. head.cmaker = "demo";
  29. head.brdflag = 1;
  30. head.vt_id = 67;
  31. head.dnmaketime = DateTime.Now;
  32. head.ddate = Convert.ToDateTime("2022-09-18");
  33. head.ccode = "OI202209180002";//放已经存在的单据号保存会生成新单据号
  34. head.cmemo = "接口生成";
  35. List<rdrecords08> bodys = new List<rdrecords08>();
  36. rdrecords08 body = new rdrecords08();
  37. body.irowno = 1;
  38. body.cinvcode = "01019002063";
  39. body.iquantity = 1;
  40. body.editprop = "A";//rdrecords08增加此字段
  41. bodys.Add(body);
  42. string sql = "";
  43. //单据头dom
  44. sql = "select m.* from KCOtherInH m with(nolock) where 1=2";
  45. domHead = getDom(sql, u8login.UfDbName);
  46. ConvertHeadXML(domHead, head);
  47. string xml = domHead.xml;
  48. //单据体dom
  49. sql = "select '' as editprop,m.* from KCOtherInB m with(nolock) where 1=2";
  50. domBody = getDom(sql, u8login.UfDbName);
  51. ConvertBodyXML(domBody, bodys);
  52. xml = domBody.xml;
  53. //保存
  54. string Msg = "", VouchId="";
  55. USERPCO.VoucherCO CO = new USERPCO.VoucherCO();
  56. CO.IniLogin(u8login, ref Msg);
  57. if (!string.IsNullOrEmpty(Msg))
  58. {
  59. throw new Exception(Msg);
  60. }
  61. bool bsucess = CO.Insert("08", domHead, domBody, domPos, ref Msg, ref con, ref VouchId, ref domMsg);
  62. if (!string.IsNullOrEmpty(Msg))
  63. {
  64. throw new Exception(Msg);
  65. }
  66. con.CommitTrans();
  67. u8login.ShutDown();
  68. MessageBox.Show("执行成功:"+ VouchId);
  69. }
  70. catch (Exception ex)
  71. {
  72. con.RollbackTrans();
  73. MessageBox.Show(ex.Message);
  74. }
  75. finally
  76. {
  77. con.Close();
  78. }
  79. }

image.png

其他出库单

  1. 其他出库单的加载、审核、弃审、删除跟其他入库单差不多,自行尝试改一下
  2. 这里重点说下出库的库存提示,刚才我们保存的存货数量1,在u8做单出2会提醒零出库控制。那我们在co中如何获取错误提示呢?
  3. Insert方法中有一个msg和 domMsg,我们可以根据这两个值进行检查

image.png

新增单据

类文件

  1. 跟上面一样,生成rdrecord09&rdrecords09用来保存单据数据

image.png

保存

  1. private void button7_Click(object sender, EventArgs e)
  2. {
  3. ADODB.Connection con = null;
  4. try
  5. {
  6. //dom
  7. MSXML2.DOMDocument domHead = new MSXML2.DOMDocument();
  8. MSXML2.DOMDocument domBody = new MSXML2.DOMDocument();
  9. MSXML2.DOMDocument domPos = new MSXML2.DOMDocument();
  10. MSXML2.IXMLDOMDocument2 domMsg = new MSXML2.DOMDocument();
  11. //登录对象
  12. U8Login.clsLogin u8login = GetU8Login();
  13. //数据库连接
  14. con = new ADODB.Connection();
  15. con.ConnectionString = u8login.UfDbName;
  16. con.Open();
  17. con.BeginTrans();
  18. //单据数据
  19. rdrecord09 head = new rdrecord09();
  20. head.cvouchtype = "09";
  21. head.cbustype = "其他出库";
  22. head.csource = "库存";
  23. head.cwhcode = "04";
  24. head.cmaker = "demo";
  25. head.brdflag = 0;
  26. head.vt_id = 85;
  27. head.dnmaketime = DateTime.Now;
  28. head.ddate = Convert.ToDateTime("2022-09-18");
  29. head.ccode = "OO20220918000001";//放已经存在的单据号保存会出现生成单据号
  30. head.cmemo = "接口生成";
  31. List<rdrecords09> bodys = new List<rdrecords09>();
  32. rdrecords09 body = new rdrecords09();
  33. body.irowno = 1;
  34. body.cinvcode = "01019002063";
  35. body.iquantity = 2;
  36. body.editprop = "A";//编辑属性:A表新增,M表修改,D表删除
  37. bodys.Add(body);
  38. string sql = "";
  39. //单据头dom
  40. sql = "select m.* from KCOtherOutH m with(nolock) where 1=2";
  41. domHead = getDom(sql, u8login.UfDbName);
  42. ConvertHeadXML(domHead, head);
  43. string xml = domHead.xml;
  44. //单据体dom
  45. sql = "select '' as editprop,m.* from KCOtherOutB m with(nolock) where 1=2";
  46. domBody = getDom(sql, u8login.UfDbName);
  47. ConvertBodyXML(domBody, bodys);
  48. xml = domBody.xml;
  49. //保存
  50. string Msg = "", VouchId = "";
  51. USERPCO.VoucherCO CO = new USERPCO.VoucherCO();
  52. CO.IniLogin(u8login, ref Msg);
  53. if (!string.IsNullOrEmpty(Msg)) { throw new Exception(Msg); }
  54. bool bsucess = CO.Insert("09", domHead, domBody, domPos, ref Msg, ref con, ref VouchId, ref domMsg);
  55. if (!bsucess)
  56. {
  57. if (!string.IsNullOrEmpty(Msg)) { throw new Exception(Msg); }
  58. xml = domMsg.xml;
  59. if (!string.IsNullOrEmpty(xml)) { throw new Exception("保存失败请查看:domMsg"); }
  60. }
  61. con.CommitTrans();
  62. u8login.ShutDown();
  63. MessageBox.Show("执行成功:" + VouchId);
  64. }
  65. catch (Exception ex)
  66. {
  67. con.RollbackTrans();
  68. MessageBox.Show(ex.Message);
  69. }
  70. finally
  71. {
  72. con.Close();
  73. }
  74. }

用数量2出返回dommsg错误,提示如下,我们可以进一步解析此xml返回客户端提示
image.png

image.png

把数量改为1,执行单据保存成功
image.png

总结

引用的错误提示

改为false
image.png

关于co

  1. 到这里你应该可以完成了其他出入库单的co接口,觉得有收获的话点个赞呗😀
  2. 其他库存接口大多类似,需要自行查看u8的单据表,观察u8的字段

    关于源码

  3. 源码我就不直接给出了,引用不多,加上我大多贴了代码,建议自行操作一遍

  4. 不想自己敲代码的话可以联系qq243927103,请我喝杯奶茶发你源码,读后有收获也可打赏一下下哦😀
  5. image.png

image.png