DataGridView单元格转decimal报错:Specified cast is not valid
解决DataGridView单元格转decimal的InvalidCastException问题
错误原因
直接用(decimal)dataGridViewCell.Value强制转换会抛出异常,核心原因是单元格值的实际类型无法直接转为decimal:
- 单元格值为
DBNull(空值状态) - 单元格存储的是字符串、整数(int/long)等其他类型,强制转换不兼容
- 单元格值为非数字格式的字符串
修复方案
1. 安全处理类型转换
放弃强制转换,改用Convert.ToDecimal()兼容多类型转换,同时处理DBNull场景;如果需要严格校验数值有效性,用decimal.TryParse()做前置验证。
2. 优化循环性能
原代码双重遍历的时间复杂度为O(n*m),数据量大时效率极低。可以用字典缓存dataGridView3中PartNumber与对应行的映射,将复杂度降至O(n+m)。
修改后的代码
基础修复版(解决转换异常)
for (int i = 0; i < dataGridView1.Rows.Count - 1; i++) { for (int y = 0; y < dataGridView3.Rows.Count - 1; y++) { // 先处理空值再比较PartNumber var partNum1 = dataGridView1.Rows[i].Cells[0].Value?.ToString(); var partNum3 = dataGridView3.Rows[y].Cells[0].Value?.ToString(); if (string.Equals(partNum1, partNum3)) { // 安全转换,空值默认按0处理 decimal qty3 = Convert.ToDecimal(dataGridView3.Rows[y].Cells[3].Value ?? 0); decimal qty1 = Convert.ToDecimal(dataGridView1.Rows[i].Cells[3].Value ?? 0); qty3 += qty1; dataGridView3.Rows[y].Cells[3].Value = qty3; } } } dataGridView3.Refresh();
性能优化版(适合大数据量)
// 缓存dataGridView3的PartNumber与对应行的映射 var partRowMap = new Dictionary<string, DataGridViewRow>(); for (int y = 0; y < dataGridView3.Rows.Count - 1; y++) { var partNum = dataGridView3.Rows[y].Cells[0].Value?.ToString(); if (!string.IsNullOrEmpty(partNum) && !partRowMap.ContainsKey(partNum)) { partRowMap.Add(partNum, dataGridView3.Rows[y]); } } // 遍历dataGridView1直接匹配求和 for (int i = 0; i < dataGridView1.Rows.Count - 1; i++) { var partNum1 = dataGridView1.Rows[i].Cells[0].Value?.ToString(); if (string.IsNullOrEmpty(partNum1) || !partRowMap.TryGetValue(partNum1, out var targetRow)) continue; decimal qty1 = Convert.ToDecimal(dataGridView1.Rows[i].Cells[3].Value ?? 0); decimal qty3 = Convert.ToDecimal(targetRow.Cells[3].Value ?? 0); targetRow.Cells[3].Value = qty3 + qty1; } dataGridView3.Refresh();
额外严谨处理
如果单元格可能存在非数字字符串,建议用decimal.TryParse做错误拦截:
// 以转换dataGridView3的Qty为例 if (!decimal.TryParse(dataGridView3.Rows[y].Cells[3].Value?.ToString(), out decimal qty3)) { // 转换失败时的兜底处理,比如设为0或者记录错误 qty3 = 0; }
内容的提问来源于stack exchange,提问作者Grayson Chee
相关产品推荐
相关产品推荐

