找回密码
 注册账号

QQ登录

只需一步,快速开始

手机号码,快捷登录

手机号码,快捷登录

初学者课程:T3自学|T6自学|U8自学软件下载课件下载工具下载资料:通资料|U8资料|NC|培训|年结积分规则 | 使用常见问题Q&A
知识库:U8 | | NC | U9 | OA | 政务U8|U9|NCC|NC65|NC65客开|NCC客开新手必读 | 任务 | 快速增金币用友QQ群[微信群]
查看: 6261|回复: 8

[技巧] U8 存储过程展开BOM表

[复制链接]
发表于 2017-4-7 16:16:14 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册账号

×
CREATE  PROCEDURE [dbo].[usp_spreadbom]
@erpdbname NVARCHAR(20),
@bomid INT,
@qty DECIMAL(28, 6)
---适用版本U8
AS
--展开方式:阶列式
--BOM状态:3
--是否使用计划比例:否
--采购件是否展开:否
--BOM展开单位:Inventory_Sub.iBOMExpandUnitType = 1

DECLARE @count INT;
DECLARE @bomlevel INT;
DECLARE @sql NVARCHAR(4000);

IF (RIGHT(@erpdbname, 2) <> '..')
BEGIN
        SET @erpdbname = @erpdbname
END;

--创建临时表
CREATE TABLE #temp
(
        Id INT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
        BomLevel INT NULL,
        BomId INT NULL,

        OpComponentId INT NULL,        
        OpSeq NCHAR(4) NULL,
        FVFlag TINYINT NULL,
        ByProductFlag BIT NULL,        
        WipType TINYINT NULL,
        WhCode NVARCHAR(10) NULL,

        ParentId INT NULL,
        ParentInvCode NVARCHAR(20) NULL,
        ParentInvName NVARCHAR(255) NULL,

        ChildId INT NULL,
        childVersion nvarchar(50) NULL,
        ChildInvCode NVARCHAR(20) NULL,
        ChildInvName NVARCHAR(255) NULL,
        ChildInvCCode NVARCHAR(255) NULL,
        ChildInvStd NVARCHAR(255) NULL,
        ChildComUnitCode NVARCHAR(35) NULL,
        ChildBSelf BIT NULL,
        ChildBPurchase BIT NULL,
        ChildBProxyForeign BIT NULL,
        ChildBomId INT NULL,

        BaseQtyN DECIMAL(28, 6) NULL,
        BaseQtyD DECIMAL(28, 6) NULL,
        ParentScrap DECIMAL(28, 6) NULL,
        CompScrap DECIMAL(28, 6) NULL,        

        Qty DECIMAL(28, 6) NULL,
        BaseQtyNCalc DECIMAL(28, 6) NULL,
        BaseQtyDCalc DECIMAL(28, 6) NULL,

);

--插入第一条初始化数据
SET @sql = '';
SET @sql = @sql + 'INSERT INTO #temp(bomlevel, childid, childVersion ,childbomid, baseqtyn, baseqtyd, baseqtyncalc, baseqtydcalc,  qty) ';
SET @sql = @sql + 'SELECT -1 AS bomlevel, bp.parentid AS childid,b.version, b.bomid AS childbomid, 1 AS baseqtyn, 1 AS baseqtyd, 1 AS baseqtyncalc, 1 AS baseqtydcalc,  1 AS qty ';
SET @sql = @sql + 'FROM ' + @erpdbname + 'bom_bom b ';
SET @sql = @sql + 'INNER JOIN ' + @erpdbname + 'bom_parent bp ';
SET @sql = @sql + 'ON b.bomid = bp.bomid ';
SET @sql = @sql + 'WHERE  bp.parentid NOT IN (SELECT partid FROM ' + @erpdbname + 'bas_part WHERE invcode IN (SELECT cinvcode FROM ' + @erpdbname + 'inventory WHERE bself = 0 AND bpurchase = 1)) ';
SET @sql = @sql + 'AND b.bomid = ' + CAST(@bomid AS VARCHAR) + '; ';
EXEC(@sql);        

--准备开始循环
SET @count = 1;
SET @bomlevel = -1;
WHILE @count > 0 BEGIN



        --插入所有子件
        SET @sql = '';
        SET @sql = @sql + 'INSERT INTO #temp(bomlevel, bomid, ';
        SET @sql = @sql + 'opcomponentid, opseq, fvflag, byproductflag, wiptype, whcode, ';
        SET @sql = @sql + 'parentid,childVersion, childid, ';
        SET @sql = @sql + 'baseqtyn, baseqtyd, parentscrap, compscrap, ';
        SET @sql = @sql + 'baseqtyncalc, baseqtydcalc,  qty) ';

        SET @sql = @sql + 'SELECT ' + CAST(@bomlevel+1 AS NVARCHAR) + ' AS bomlevel, b.bomid, ';
        SET @sql = @sql + 'bc.opcomponentid, bc.opseq, bc.fvflag, bc.byproductflag, bco.wiptype, bco.whcode, ';
        SET @sql = @sql + 'bp.parentid,b.version, bc.componentid, ';
        SET @sql = @sql + 'bc.baseqtyn, bc.baseqtyd, bp.parentscrap, bc.compscrap, ';
        SET @sql = @sql + '(CASE WHEN bc.fvflag = 0 THEN 1 ELSE t.baseqtyncalc END) * bc.baseqtyn AS baseqtyncalc, ';
        SET @sql = @sql + '(CASE WHEN bc.fvflag = 0 THEN 1 ELSE t.baseqtydcalc END) * bc.baseqtyd AS baseqtydcalc, ';
        SET @sql = @sql + '(CASE WHEN bc.fvflag = 0 THEN 1 ELSE t.qty END) * (CASE bc.fvflag WHEN 0 THEN (1 + bc.compscrap / 100) ELSE (1 + bc.compscrap / 100) / (1 - bp.parentscrap / 100) END) AS qty ';

        SET @sql = @sql + 'FROM (SELECT childbomid, baseqtyncalc, baseqtydcalc, qty FROM #temp WHERE bomlevel = ' + CAST(@bomlevel AS NVARCHAR) + ' AND childbomid IS NOT NULL) t ';
        SET @sql = @sql + 'INNER JOIN ' + @erpdbname + 'bom_bom b ';
        SET @sql = @sql + 'ON t.childbomid = b.bomid ';        
        SET @sql = @sql + 'INNER JOIN ' + @erpdbname + 'bom_parent bp ';
        SET @sql = @sql + 'ON b.bomid = bp.bomid ';
        SET @sql = @sql + 'INNER JOIN ' + @erpdbname + 'bom_opcomponent bc ';
        SET @sql = @sql + 'ON b.bomid = bc.bomid ';
        SET @sql = @sql + 'INNER JOIN ' + @erpdbname + 'bom_opcomponentopt bco ';
        SET @sql = @sql + 'ON bc.optionsid = bco.optionsid ';        
        SET @sql = @sql + 'WHERE   b.bomtype = 1 ';
        SET @sql = @sql + 'AND bp.parentid NOT IN (SELECT partid FROM ' + @erpdbname + 'bas_part WHERE invcode IN (SELECT cinvcode FROM ' + @erpdbname + 'inventory WHERE bself = 0 AND bpurchase = 1)) ';
        SET @sql = @sql + 'ORDER BY bc.sortseq, bc.opseq; ';
        EXEC(@sql);        



        --创建临时表
        CREATE TABLE #temp_bom_parent
        (
                Id INT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
                ParentId INT NULL,
                BomId INT NULL
        );

        --有后续子件的,获取最新版本的BOM
        SET @sql = '';
        SET @sql = @sql + 'INSERT INTO #temp_bom_parent(parentid, bomid) ';
        SET @sql = @sql + 'SELECT t.childid, b.bomid ';
        SET @sql = @sql + 'FROM (SELECT childid FROM #temp WHERE bomlevel = ' + CAST(@bomlevel+1 AS NVARCHAR) + ') t ';        
        SET @sql = @sql + 'INNER JOIN ' + @erpdbname + 'bom_parent bp ';
        SET @sql = @sql + 'ON t.childid = bp.parentid ';
        SET @sql = @sql + 'INNER JOIN ' + @erpdbname + 'bom_bom b ';
        SET @sql = @sql + 'ON bp.bomid = b.bomid ';
        SET @sql = @sql + 'INNER JOIN ' + @erpdbname + ' bas_part bsp ';
        SET @sql = @sql + 'ON bp.parentid = bsp.partid ';
        SET @sql = @sql + 'INNER JOIN ' + @erpdbname + 'inventory inv on bsp.invcode = inv.cinvcode ';
        SET @sql = @sql + 'WHERE  b.bomtype = 1 ';
        SET @sql = @sql + 'AND inv.bself = 1 ';
    SET @sql = @sql + 'AND NOT EXISTS ( ';
        SET @sql = @sql + '    SELECT * ';
        SET @sql = @sql + '    FROM ' + @erpdbname + 'bom_bom b2 ';
        SET @sql = @sql + '    INNER JOIN ' + @erpdbname + 'bom_parent bp2 ';
        SET @sql = @sql + '    ON b2.bomid = bp2.bomid ';
        SET @sql = @sql + '    AND bp2.parentid = bp.parentid ';
        SET @sql = @sql + '    WHERE  b2.bomtype = 1 ';
        SET @sql = @sql + '    AND bp2.parentid NOT IN (SELECT partid FROM ' + @erpdbname + 'bas_part WHERE invcode IN (SELECT cinvcode FROM ' + @erpdbname + 'inventory WHERE bself = 0 AND bpurchase = 1)) ';
        SET @sql = @sql + '    AND b2.versioneffdate > b.versioneffdate ';
        SET @sql = @sql + '); ';
        EXEC(@sql);

        --更新最新的BOMID
        UPDATE #temp
        SET childbomid = tbp.bomid
        FROM #temp_bom_parent tbp
        WHERE bomlevel = @bomlevel+1
        AND #temp.childid = tbp.parentid;        

        DROP TABLE #temp_bom_parent;

        --计数决定是否完成展BOM
        SELECT @count = COUNT(*)
        FROM #temp
        WHERE bomlevel = @bomlevel+1 ;

        SET @bomlevel = @bomlevel + 1;

END;

--更新父件的物料信息
SET @sql = '';
SET @sql = @sql + 'UPDATE #temp ';
SET @sql = @sql + 'SET parentinvcode = bp.invcode, parentinvname = i.cinvname ';
SET @sql = @sql + 'FROM ' + @erpdbname + 'bas_part bp ';
SET @sql = @sql + 'INNER JOIN ' + @erpdbname + 'inventory i ';
SET @sql = @sql + 'ON bp.invcode = i.cinvcode ';
SET @sql = @sql + 'WHERE #temp.parentid = bp.partid; ';
EXEC(@sql);

--更新子件的物料信息
SET @sql = '';
SET @sql = @sql + 'UPDATE #temp ';
SET @sql = @sql + 'SET childinvcode = bp.invcode, childinvname = i.cinvname, ChildInvCCode = i.cinvccode,childinvstd = i.cinvstd, ';
SET @sql = @sql + 'childcomunitcode = i.ccomunitcode, childbself = i.bself, childbpurchase = i.bpurchase, childbproxyforeign = i.bproxyforeign ';
SET @sql = @sql + 'FROM ' + @erpdbname + 'bas_part bp ';
SET @sql = @sql + 'INNER JOIN ' + @erpdbname + 'inventory i ';
SET @sql = @sql + 'ON bp.invcode = i.cinvcode ';
SET @sql = @sql + 'WHERE #temp.childid = bp.partid; ';
EXEC(@sql);

--计算数量
UPDATE #temp
SET qty = @qty * qty * baseqtyncalc / baseqtydcalc;


SELECT *
FROM #temp
where  isnull(ChildBomId,'') = ''
ORDER BY bomlevel, id;

DROP TABLE #temp;

GO

发表于 2017-4-7 16:33:56 | 显示全部楼层
不需要那么复杂,SQL2005版本的其实写起来比较简单。
我有导入和导出BOM的工具,
回复 点赞 拍砖

使用道具 举报

发表于 2017-4-10 09:00:10 | 显示全部楼层
我靠,也是人才啊
回复 点赞 拍砖

使用道具 举报

发表于 2017-7-29 10:19:59 | 显示全部楼层
yaoxiaoxiang 发表于 2017-4-7 16:33
不需要那么复杂,SQL2005版本的其实写起来比较简单。
我有导入和导出BOM的工具,

BOM 导出工具可以共享吗

回复 点赞 拍砖

使用道具 举报

发表于 2018-6-3 18:31:58 | 显示全部楼层
yaoxiaoxiang 发表于 2017-4-7 16:33
不需要那么复杂,SQL2005版本的其实写起来比较简单。
我有导入和导出BOM的工具,

工具在哪里?
回复 点赞 拍砖

使用道具 举报

发表于 2023-4-14 10:34:55 | 显示全部楼层
多谢分享,学习了
回复 点赞 拍砖

使用道具 举报

发表于 2023-4-14 11:59:22 | 显示全部楼层
多谢分享!
回复 点赞 拍砖

使用道具 举报

发表于 2024-1-15 09:51:39 | 显示全部楼层
多谢。收藏一下
回复 点赞 拍砖

使用道具 举报

发表于 2024-2-21 11:42:11 | 显示全部楼层
多谢。收藏一下
回复 点赞 拍砖

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

QQ|站长微信|Archiver|手机版|小黑屋|用友之家 ( 蜀ICP备07505338号|51072502110008 )

GMT+8, 2024-5-6 02:54 , Processed in 0.023038 second(s), 11 queries , Gzip On, Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表