Char2Nums是一个用来将编号类的字符串解析成三个属性:首字符+数值+尾字符,方便我们获取相应的数值进行计算。比较典型的应用场景就是根据已有的编号然后自动猜测填充后面的数据。
构造函数:
Char2Nums(string strChars)
我们只需要将需要解析的字符串传递进构造函数即可。
属性名称 | 说明 |
BeginChar | 首部字符串,即数值前面部分字符串。 |
MidNum | 数值部分 |
IsFormatFixLengthNumber | 数值部分是否为固定长度的数值。 |
NumLength | 数字部分的长度。 |
EndChar | 尾部字符串。即数值后面部分的字符串。 |
'根据字符串初始化一个Char2Nums对象 Dim num1 As Char2Nums = New Char2Nums("BH0002XL") '首部字符串 Proj.MsgDebug.Add(num1.BeginChar) '返回:BH '中间数值部分 Proj.MsgDebug.Add(num1.MidNum) '返回:0002 '尾部字符串 Proj.MsgDebug.Add(num1.EndChar) '返回:XL '数值部分长度 Proj.MsgDebug.Add(num1.NumLength) '返回:4 '数值部分是否为固定长度的数值。 Proj.MsgDebug.Add(num1.IsFormatFixLengthNumber) '返回:True |
下面是一个比较典型的示例,实现字符串的序列填充。
VB.Net |
'获得当前表 Dim tblMain As SmGrid = Proj.CurrentSmGrid '如果当前表为空,则退出 If tblMain Is Nothing Then Return '获得当前选区 Dim rg As CellRange = tblMain.Selection '如果选区有数据,并且大于2行 If rg.r1 <> rg.r2 AndAlso rg.r2 - rg.r1 >= 2 Then '获得第一个单元格值 Dim dataFirstCell As Object = tblMain.GetData(rg.TopRow, rg.LeftCol) '获得第二个单元格值 Dim dataSecondCell As Object = tblMain.GetData(rg.TopRow + 1, rg.LeftCol) '如果第一、第二个单元格值都不为空 If dataFirstCell IsNot Nothing AndAlso dataSecondCell IsNot Nothing Then '获得列名称 Dim strColName As String = tblMain.Cols(rg.LeftCol).Name '获得列数据类型 Dim actualDataType As Type = tblMain.Cols(strColName).DataType '获得数据列 Dim colData As ColData = tblMain.DataTableHelp.DataCols(strColName) '如果该列是字符型 If colData.IsString Then '根据第一个单元格的值初始化一个Char2Nums对象 Dim num1 As Char2Nums = New Char2Nums(dataFirstCell.ToString()) '根据第二个单元格的值初始化一个Char2Nums对象 Dim num2 As Char2Nums = New Char2Nums(dataSecondCell.ToString()) '如果检测到字符串中的数值部分不为空 If num1.MidNum.Length > 0 AndAlso num2.MidNum.Length > 0 AndAlso (Double.Parse(num1.MidNum)) + Double.Parse(num2.MidNum) > 0 Then '获得两个数值之间的步进值(差值) Dim dblStep As Double = (Double.Parse(num2.MidNum)) - Double.Parse(num1.MidNum) '从第三个行开始按序列填充数据 For i As Integer = 2 To (rg.r2 - rg.r1) '根据第一个单元格中的中间数值+序列与步进值计算出当前值 Dim dblNum As Double = (Double.Parse(num1.MidNum) + i * dblStep) Dim strNum As String = "" '根据数据格式格式化计算出的数值 If num1.IsFormatFixLengthNumber Then strNum = dblNum.ToString(New String("0"c, num1.NumLength)) Else strNum = dblNum.ToString() End If '获得对应的行对象 Dim dr As RowData = tblMain.Rows(rg.r1 + i).GetRowData() '如果行对象不为空还有没有被锁定,则将最后的字符串拼接出来赋值给单元格 If dr IsNot Nothing AndAlso Not dr.Locked Then dr(strColName) = (num1.BeginChar & strNum) + num1.EndChar End If Next End If End If End If End If |
C# |
// 获得当前表 SmGrid tblMain = Proj.CurrentSmGrid; // 如果当前表为空,则退出 if (tblMain == null) return; // 获得当前选区 CellRange rg = tblMain.Selection; // 如果选区有数据,并且大于2行 if (rg.r1 != rg.r2 && rg.r2 - rg.r1 >= 2) { // 获得第一个单元格值 object dataFirstCell = tblMain.GetData(rg.TopRow, rg.LeftCol); // 获得第二个单元格值 object dataSecondCell = tblMain.GetData(rg.TopRow + 1, rg.LeftCol); // 如果第一、第二个单元格值都不为空 if (dataFirstCell != null && dataSecondCell != null) { // 获得列名称 string strColName = tblMain.Cols[rg.LeftCol].Name; // 获得列数据类型 Type actualDataType = tblMain.Cols[strColName].DataType; // 获得数据列 ColData colData = tblMain.DataTableHelp.DataCols[strColName]; // 如果该列是字符型 if (colData.IsString) { // 根据第一个单元格的值初始化一个Char2Nums对象 Char2Nums num1 = new Char2Nums(dataFirstCell.ToString()); // 根据第二个单元格的值初始化一个Char2Nums对象 Char2Nums num2 = new Char2Nums(dataSecondCell.ToString()); // 如果检测到字符串中的数值部分不为空 if (num1.MidNum.Length > 0 && num2.MidNum.Length > 0 && (double.Parse(num1.MidNum)) + double.Parse(num2.MidNum) > 0) { // 获得两个数值之间的步进值(差值) double dblStep = (double.Parse(num2.MidNum)) - double.Parse(num1.MidNum); // 从第三个行开始按序列填充数据 for (int i = 2; i <= (rg.r2 - rg.r1); i++) { // 根据第一个单元格中的中间数值+序列与步进值计算出当前值 double dblNum = (double.Parse(num1.MidNum) + i * dblStep); string strNum = ""; // 根据数据格式格式化计算出的数值 if (num1.IsFormatFixLengthNumber) strNum = dblNum.ToString(new string('0', num1.NumLength)); else strNum = dblNum.ToString(); // 获得对应的行对象 RowData dr = tblMain.Rows[rg.r1 + i].GetRowData(); // 如果行对象不为空还有没有被锁定,则将最后的字符串拼接出来赋值给单元格 if (dr != null && !dr.Locked) { dr[strColName] = num1.BeginChar + strNum + num1.EndChar; } } } } } } |