# G046_洪城编码工具 **Repository Path**: LPBStudio/G046_HCPLMCodeTools ## Basic Information - **Project Name**: G046_洪城编码工具 - **Description**: 洪城PLM文档预处理工具 - **Primary Language**: C# - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-07-28 - **Last Updated**: 2025-08-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # G046_洪城编码工具 #### 介绍 洪城PLM文档预处理工具 PLM系统文档录入编码预处理程序方案 #### 软件架构 ## 一、方案的目的 在PLM系统的唯一性标识仅为物料编码的情况下,简化用户的编码工作。让所有的编码工作集中在同一功能下,实现自动的识别重复物料并给出编码重用建议、自动对新物料新自制件进行编码、自动通过物料编码实现借用机制等功能,初步实现智能化的编码管理工作。该功能将极大的减少设计工作人员在编码工作上的负担,极大的提高工作效率。而该能也能保证PLM系统对唯一性标识管理的统一性,增强系统的稳固性。 ## 二、方案的基础前提 - 1、在PLM系统中,二维CAD工具中的产品结构(BOM结构)是通过装配图中明细表条目的编码字段与具体零件图纸上标题栏信息中编码字段之间的关联建立的,同时在PLM系统中,所有文档及信息的唯一性标识仅为物料编码。 - 2、在PLM之前,在设计过程中,二维CAD工具中,装配图上的编码字段是不显示,不参与设计过程的。其产品结构(BOM结构)在当前目录下的文档间,是通过装配图中明细表条目的图号字段与具体零件图纸上标题栏信息中图号字段之间的关联建立的。在PLM系统之前的文档标题栏及明细表中都必须有编码字段,但全程都不处理物料编码。 - 3、物料编码的唯一管理由PLM对应模块实现,并且编码规则能够让物料编码可以在无需用户参与提供参数信息的情况下自动生成。 - 4、编码预处理程序仅在文档首次录入之前进行编码处理,从而保证PLM实际录入的文档中编码完整有效,不参与以后任何PLM业务,包括文档修改及变更工作。因此系统依然需要提供功能来检查明细表条目中的文字信息与编码对应的属性集是否匹配,从而避免图纸上的图形信息与编码库中信息的错位问题。 ## 三、方案框架 - 1、编码预处理程序是处于PLM工作范围的边界处,是PLM外工作与PLM系统的唯一性接口,现阶段仅针对DWG、EXB等二维CAD图档,其他文档,比如Word、Excel及ZIP等文件,其编码方式不同,不做预处理其编码问题由PLM进行管理。 - 2、编码的预处理程序是由PLM在录入文档时触发启动,在文档录入到PLM阶段时,当用户选择了需要上传的文件之后,启动编码预处理程序,程序将会有工作界面,在工作界面中完成相关编码的预处理工作。PLM将用户欲提交的所有文件的路径及文件名信息传递给编码预处理程序,同时传递用户信息,如需要还需传递所处项目等其他信息。 - 3、编码预处理程序需要PLM的以下功能: - 3.1、需要PLM提供读取文档标题栏及明细表信息的API接口,编码预处理程序将通过该API读取所有文档的标题栏及明细表结构及对应信息; - 3.2、编码预处理程序处理过程可能产生新的信息,比如文档的编码等,这些信息需要通过一定的方式回传到PLM的处理进程,从而完成文档的录入工作。对应数据的回传可以采用以下2种方案任选: - A、通过PLM提供的API接口,直接将编码写入到目标文档的明细表及标题栏对应的属性中,并将修改后的文档作为PLM提交的文档对象;该方式优点在于程序边界清晰,PLM修改工作量较少。 - B、通过中间文件进行信息传递,比如建立BOM关系说明,通过文件名及编码的对应关系表传递,该方案可以不需要再写入文档,但需要PLM进行相关解析及认证工作。 - 4、编码预处理程序的关闭将回传相关结果,如果全部完成相关工作,并写回相关编码数据,将返回True,否则返回False,表示用户放弃录入工作。 ## 四、后续问题 该编码预处理程序现阶段仅能够处理二维CAD文档,并协助设计工作人员完成编码工作,但本项目会使用到CAXA公司的三维设计工具,是否能够协助三维设计文档及是否需要对三维设计文档进行编码预处理程序,需要更进一步分析 #### 软件架构 - 1、数据库服务器地址:192.168.1.190或192.168.0.49;用户名:sa;密码:HCca2515lee - 2、数据表:PLM2025.dbo.CODE2_CODE为所有申请的编码信息表; ### C++/CLI中间层的使用 作用:让C++能够通过该dll库,调用C#编写的dll库并进入C#的代码空间; 可以支持.Net Freamework也可以支持.Net Core #### 注意: 1、在VS2022中,必须通过安装工具,在“单个组件”中安装“C++/CLI支持”,并建议选择最后版本,安装之后在新创建中将出现CLR项目模板; 2、创建CLR项目后,在添加引用中,添加C#项目的dll库,此时,才能够通过C#的“命令空间.类型名称”调用C#的对象及函数; 3、对于C++传递的参数中的字符串,必须经过msclr::interop::marshal_as进行转换; 4、本dll库被C++程序调用后,需要调试的时候,必须将C++程序的“属性”“调试器”“调试器类型”设置为“混合+目标框架”; 5、本dll库被C++程序调用后,进入调试的模式后,在LoadLibraryW导入中间库之后,在“调试”“窗口”“模块”的列表中将出现中间库的名称, 此时用反键菜单将其设置“始终自动加载”后,将可以进入C++/CLI中间库的断点,也能进入C#空间的断点; #### 特技 1、SQL Server中创建每日更新的流水码 1.1、创建辅助表(记录序列重置状态)用于跟踪当天是否已初始化序列,避免重复重置: ```sql CREATE TABLE SequenceResetLog ( ResetDate DATE PRIMARY KEY, -- 日期主键 IsInitialized BIT NOT NULL DEFAULT 0 -- 标记当天序列是否已初始化 ); ``` 1.2、创建存储过程(核心逻辑)负责检查日期、重置序列(如需)、生成流水码: ```sql CREATE PROCEDURE GetDailySequenceSerial @SerialNumber VARCHAR(14) OUTPUT -- 输出:8+6=14位流水码 AS BEGIN SET NOCOUNT ON; DECLARE @Today DATE = CAST(GETDATE() AS DATE); DECLARE @SeqName NVARCHAR(128) = 'Daily6DigitSeq'; -- 序列名称 -- 定期清理历史数据:对SequenceResetLog保留最近 30 天记录,避免表过大。 EXEC('DELETE FROM SequenceResetLog WHERE ResetDate < DATEADD(DAY, -30, GETDATE());') -- 1. 检查并初始化当天序列(加锁确保并发安全) BEGIN TRANSACTION; -- 检测当天是否已初始化序列 IF NOT EXISTS (SELECT 1 FROM SequenceResetLog WITH (UPDLOCK, HOLDLOCK) WHERE ResetDate = @Today AND IsInitialized = 1) BEGIN -- 若存在旧序列则删除(每天重建一次) IF EXISTS (SELECT 1 FROM sys.sequences WHERE name = @SeqName) BEGIN EXEC('DROP SEQUENCE ' + @SeqName); END -- 创建新序列(6位范围:1-999999,缓存1000个值提升性能) EXEC( 'CREATE SEQUENCE ' + @SeqName + ' AS INT START WITH 1 INCREMENT BY 1 MINVALUE 1 MAXVALUE 999999 NO CYCLE CACHE 1000;' -- 缓存1000个值,减少数据库IO ); -- 记录当天已初始化 MERGE INTO SequenceResetLog AS target USING (SELECT @Today AS ResetDate) AS source ON (target.ResetDate = source.ResetDate) WHEN MATCHED THEN UPDATE SET IsInitialized = 1 WHEN NOT MATCHED THEN INSERT (ResetDate, IsInitialized) VALUES (source.ResetDate, 1); END COMMIT TRANSACTION; -- 2. 获取下一个序列值并生成流水码 DECLARE @NextNum INT; SELECT @NextNum = NEXT VALUE FOR Daily6DigitSeq; -- 原子操作,确保唯一 -- 拼接格式:8位年月日(如20250821)+ 6位补零序号(如000001) SET @SerialNumber = CONVERT(VARCHAR(8), @Today, 112) + RIGHT('000000' + CAST(@NextNum AS VARCHAR(6)), 6); END; ``` 1.3、使用SQL语句进行并发测试: ```sql DECLARE @Serial1 VARCHAR(14), @Serial2 VARCHAR(14), @Serial3 VARCHAR(14); -- 3. 多次调用存储过程 EXEC dbo.GetDailySequenceSerial @SerialNumber = @Serial1 OUTPUT; EXEC dbo.GetDailySequenceSerial @SerialNumber = @Serial2 OUTPUT; EXEC dbo.GetDailySequenceSerial @SerialNumber = @Serial3 OUTPUT; -- 4. 输出结果并验证格式 SELECT @Serial1 AS SerialNumber1, @Serial2 AS SerialNumber2, @Serial3 AS SerialNumber3; ``` 1.4、使用C#语言测试: ```csharp using (SqlConnection conn = new SqlConnection("你的连接字符串")) { conn.Open(); using (SqlCommand cmd = new SqlCommand("GetDailySequenceSerial", conn)) { cmd.CommandType = System.Data.CommandType.StoredProcedure; // 注册输出参数 var outputParam = new SqlParameter("@SerialNumber", System.Data.SqlDbType.VarChar, 14) { Direction = System.Data.ParameterDirection.Output }; cmd.Parameters.Add(outputParam); cmd.ExecuteNonQuery(); // 输出结果如:20250821000001、20250821000002... string serial = outputParam.Value.ToString(); } } ``` 2、Git错误non-fast-forward的解决方法 当要push代码到git时,出现提示: ~~~ $ git push origin master To ../remote/ ! [rejected] master -> master (non-fast-forward) error: failed to push some refs to '../remote/' ~~~ 产生原因: 别人上传到远程仓库后,你没有及时的同步(、拉取)到本地,但是你同时又添加了一些内容(提交),以致于你在提交时,它会检测到你之前从远程仓库拉取的时候的仓库状态和现在的不一样。于是,它为了安全起见拒绝了你的提交(然后就报了这个错误)。 再者我们可以简单来理解这个问题:我们从字面上理解“non-fast-forward”,可以认为是“不能快速前进”,我觉得有个广告说得好:车到山前必有路……但是路有好走的路,也有不好走的路;而遇到不好走的路时(比如前方遇到拦路石,或者是前方出现岔路),我们就不得不停下来思考“以后的路该怎么走”了,我们“不仅要低头赶路,也要抬头看路”就是这个意思。 “不能快速前进”的原因是因为路不一样了,变得不好走了;体现在git里面就是提交历史出现分叉,主线不再是一条直线,而是在前端出现了分叉,git不知道该如何前进,所以报错了,让你来觉得走哪条路! 解决办法: 1、先把git的东西fetch到你本地然后merge后再push ``` $ git fetch origin master $ git rebase FETCH_HEAD ``` 回到VS系统,对比修改并接受新的修改后。 或者直接执行将修改后的文件增加进去 ~~~ $ git add README.md ~~~ 然后执行: ~~~ $ git rebase --continue ~~~ 进入VIM编辑: ~~~ :q! ~~~