' ============================================================================== ' 模块: M06_ModelParser ' 职责: 产品型号解析,从完整产品型号中提取关键参数 ' ' 产品型号结构: [表头]|[表盘]|[附件]|[法兰隔膜] ' 表头结构: [型号]-[公称外径].[安装形式].[壳体形式].[过程连接&接液材质].[量程范围].[仪表特性] ' ' 示例: YTHN-100.A0.531.G123.M04.Y3|BP-088.2312.B09.0A3 ' 表头: YTHN-100.A0.531.G123.M04.Y3 ' azxs: A0, bkxs: 531, gclj: G12, jycz: 3, lcfw: M04, fjgn: Y3 ' ' 注意: 仅处理表头部分,其他部分(表盘、附件、法兰隔膜)暂时丢弃 ' ============================================================================== Option Explicit ' 模块级变量 - 错误记录器 Private g_Logger As clsErrorLogger ' ------------------------------------------------------------------------------ ' 初始化型号解析器 ' ------------------------------------------------------------------------------ Public Sub InitModelParser(logger As clsErrorLogger) Set g_Logger = logger End Sub ' ------------------------------------------------------------------------------ ' 主入口: 解析产品型号 ' ' 输入: ' modelString - 完整的产品型号字符串 ' ' 输出: ' Object (Scripting.Dictionary) - 包含提取的参数 ' 键值对: "xh"->型号, "gcwj"->公称外径, "azxs"->安装形式, ' "bkxs"->表壳形式, "gclj"->过程连接, "jycz"->接液材质, ' "lcfw"->量程范围, "fjgn"->附加功能 ' ' 示例: ' Set params = ParseProductModel("YTHN-100.A0.531.G123.M04.Y3|BP-088.2312.B09.0A3") ' ' params("azxs") = "A0" ' ' params("gclj") = "G12" ' ' params("jycz") = "3" ' ------------------------------------------------------------------------------ Public Function ParseProductModel(ByVal modelString As String) As Object On Error GoTo ErrorHandler Dim params As Object Set params = CreateObject("Scripting.Dictionary") ' 预处理:去除前后空格 modelString = Trim(modelString) ' 如果型号为空,返回空字典 If Len(modelString) = 0 Then Set ParseProductModel = params Exit Function End If ' 步骤1: 提取表头部分(第一个管道符之前的部分) Dim headerPart As String headerPart = ExtractHeaderPart(modelString) If Len(headerPart) = 0 Then If Not g_Logger Is Nothing Then g_Logger.Record 0, "M06.ParseProductModel", "ModelParseError", _ "无法提取表头部分,型号可能为空或格式错误", modelString End If Set ParseProductModel = params Exit Function End If ' 步骤2: 分割表头为段 Dim segments As Variant segments = SplitHeaderPart(headerPart) If Not IsArray(segments) Then If Not g_Logger Is Nothing Then g_Logger.Record 0, "M06.ParseProductModel", "ModelParseError", _ "表头分割失败", headerPart End If Set ParseProductModel = params Exit Function End If ' 步骤3: 验证段数是否足够 If UBound(segments) - LBound(segments) + 1 < MODEL_HEADER_MIN_SEGMENTS Then If Not g_Logger Is Nothing Then g_Logger.Record 0, "M06.ParseProductModel", "ModelParseError", _ "表头段数不足,需要至少" & MODEL_HEADER_MIN_SEGMENTS & "段,实际" & _ (UBound(segments) - LBound(segments) + 1) & "段", headerPart End If End If ' 步骤4: 提取型号和公称外径(预留,暂不参与BOM匹配) Call ExtractModelAndSize(headerPart, params) ' 步骤5: 提取各参数 ' 注意:segments(0)是"型号-公称外径",需要从segments(1)开始提取参数 ' 提取原始值 Dim azxsRaw As String, bkxsRaw As String Dim gcljRaw As String, jyczRaw As String Dim lcfwRaw As String, fjgnRaw As String If UBound(segments) - LBound(segments) + 1 >= 2 Then azxsRaw = ExtractAzxs(segments(1)) End If If UBound(segments) - LBound(segments) + 1 >= 3 Then bkxsRaw = ExtractBkxs(segments(2)) End If If UBound(segments) - LBound(segments) + 1 >= 4 Then Call ExtractGcljAndJycz(segments(3), gcljRaw, jyczRaw) End If If UBound(segments) - LBound(segments) + 1 >= 5 Then lcfwRaw = ExtractLcfw(segments(4)) End If If UBound(segments) - LBound(segments) + 1 >= 6 Then fjgnRaw = ExtractFjgn(segments, 5) End If ' 步骤6: 应用映射(如果映射器已初始化) If M06A_Mapper.IsInitialized() Then ' 应用azxs和lcfw映射,返回双值格式(raw,mapped) If Len(azxsRaw) > 0 Then params("azxs") = M06A_Mapper.MapAzxs(azxsRaw) End If If Len(lcfwRaw) > 0 Then params("lcfw") = M06A_Mapper.MapLcfw(lcfwRaw) End If Else ' 映射器未初始化,使用原始值 If Len(azxsRaw) > 0 Then params("azxs") = azxsRaw End If If Len(lcfwRaw) > 0 Then params("lcfw") = lcfwRaw End If End If ' 添加其他参数(不需要映射) If Len(bkxsRaw) > 0 Then params("bkxs") = bkxsRaw End If If Len(gcljRaw) > 0 Then params("gclj") = gcljRaw End If If Len(jyczRaw) > 0 Then params("jycz") = jyczRaw End If If Len(fjgnRaw) > 0 Then params("fjgn") = fjgnRaw End If Set ParseProductModel = params Exit Function ErrorHandler: If Not g_Logger Is Nothing Then g_Logger.Record 0, "M06.ParseProductModel", "SystemError", _ "解析过程发生错误: " & Err.Description, modelString End If Set ParseProductModel = CreateObject("Scripting.Dictionary") End Function ' ------------------------------------------------------------------------------ ' 提取表头部分(管道符之前) ' ' 输入: YTHN-100.A0.531.G123.M04.Y3|BP-088.2312.B09.0A3 ' 输出: YTHN-100.A0.531.G123.M04.Y3 ' ------------------------------------------------------------------------------ Private Function ExtractHeaderPart(ByVal fullModel As String) As String Dim pipePos As Long pipePos = InStr(fullModel, MODEL_SEPARATOR_PIPELINE) If pipePos > 0 Then ExtractHeaderPart = Left(fullModel, pipePos - 1) Else ExtractHeaderPart = fullModel End If End Function ' ------------------------------------------------------------------------------ ' 分割表头部分为段数组 ' ' 输入: YTHN-100.A0.531.G123.M04.Y3 ' 输出: Array("YTHN-100", "A0", "531", "G123", "M04", "Y3") ' ------------------------------------------------------------------------------ Private Function SplitHeaderPart(ByVal headerPart As String) As Variant ' 按点号分割 Dim rawSegments As Variant rawSegments = Split(headerPart, MODEL_SEPARATOR_DOT) ' 如果分割失败或结果为空 If Not IsArray(rawSegments) Then SplitHeaderPart = Null Exit Function End If ' 去除每个段的空格 Dim i As Long For i = LBound(rawSegments) To UBound(rawSegments) rawSegments(i) = Trim(CStr(rawSegments(i))) Next i SplitHeaderPart = rawSegments End Function ' ------------------------------------------------------------------------------ ' 提取型号和公称外径(预留字段) ' ' 输入: YTHN-100 ' 输出: params("xh")="YTHN", params("gcwj")="100" ' ------------------------------------------------------------------------------ Private Sub ExtractModelAndSize(ByVal firstSegment As String, ByRef params As Object) Dim dashPos As Long dashPos = InStr(firstSegment, "-") If dashPos > 1 Then params("xh") = Left(firstSegment, dashPos - 1) Dim afterDash As String afterDash = Mid(firstSegment, dashPos + 1) ' 提取-号后的数字部分(公称外径) ' 因为firstSegment是"YTHN-100.A0...",需要去掉后面的点号内容 Dim dotPos As Long dotPos = InStr(afterDash, ".") If dotPos > 0 Then params("gcwj") = Left(afterDash, dotPos - 1) Else params("gcwj") = afterDash End If End If End Sub ' ------------------------------------------------------------------------------ ' 提取安装形式 ' ' 输入: A0 ' 输出: A0 ' ' 规则: 直接返回第一段的值 ' ------------------------------------------------------------------------------ Private Function ExtractAzxs(ByVal segment As String) As String ExtractAzxs = Trim(segment) End Function ' ------------------------------------------------------------------------------ ' 提取表壳形式 ' ' 输入: 531 ' 输出: 531 ' ' 规则: 直接返回第二段的值 ' ------------------------------------------------------------------------------ Private Function ExtractBkxs(ByVal segment As String) As String ExtractBkxs = Trim(segment) End Function ' ------------------------------------------------------------------------------ ' 提取过程连接和接液材质 ' ' 输入: G123 ' 输出: gclj="G12", jycz="3" ' ' 规则: ' - 过程连接: 去除最后一位 ' - 接液材质: 最后一位 ' ------------------------------------------------------------------------------ Private Sub ExtractGcljAndJycz(ByVal segment As String, ByRef gclj As String, ByRef jycz As String) segment = Trim(segment) If Len(segment) >= 1 Then jycz = Right(segment, 1) If Len(segment) > 1 Then gclj = Left(segment, Len(segment) - 1) Else gclj = "" End If Else gclj = "" jycz = "" End If End Sub ' ------------------------------------------------------------------------------ ' 提取量程范围 ' ' 输入: M04 ' 输出: M04 ' ' 规则: 直接返回第四段的值 ' ------------------------------------------------------------------------------ Private Function ExtractLcfw(ByVal segment As String) As String ExtractLcfw = Trim(segment) End Function ' ------------------------------------------------------------------------------ ' 提取附加功能 ' ' 输入: segments数组,起始索引为4 ' 输出: Y3 或 N1,N2 或 N1.N2 ' ' 规则: ' - 从第五段开始,所有段合并为附加功能 ' - 用逗号或点号分隔的多个功能,保留原分隔符 ' - 示例: Y3 -> Y3 ' - 示例: N1,N2.Y3 -> N1,N2,Y3 ' ------------------------------------------------------------------------------ Private Function ExtractFjgn(ByRef segments As Variant, ByVal startIndex As Long) As String Dim result As String result = "" Dim i As Long For i = startIndex To UBound(segments) Dim segment As String segment = Trim(CStr(segments(i))) If Len(segment) > 0 Then ' 替换点号为逗号(统一分隔符) segment = Replace(segment, MODEL_SEPARATOR_DOT, ",") If Len(result) > 0 Then result = result & "," & segment Else result = segment End If End If Next i ExtractFjgn = result End Function