C# 预测Excel将如何使用Postgres函数解释字符串
在我的工作场所中,我们有零件号项目编号,当输入Excel时,这些编号通常会转换为Excel认为用户的意思 例如,Excel进行以下更改:C# 预测Excel将如何使用Postgres函数解释字符串,c#,excel,perl,postgresql,C#,Excel,Perl,Postgresql,在我的工作场所中,我们有零件号项目编号,当输入Excel时,这些编号通常会转换为Excel认为用户的意思 例如,Excel进行以下更改: 00001234 => 1234 005678.0 => 5678 1234.560 => 1234.56 由于电子表格来自我们无法控制的来源,我们无法尝试控制Excel本身的行为 我有一个用VSTO C固定在Excel上的实用程序,它会转到Postgres表,尝试查找Excel零件号并将其转换回真实的零件号。简而言
00001234 => 1234
005678.0 => 5678
1234.560 => 1234.56
由于电子表格来自我们无法控制的来源,我们无法尝试控制Excel本身的行为
我有一个用VSTO C固定在Excel上的实用程序,它会转到Postgres表,尝试查找Excel零件号并将其转换回真实的零件号。简而言之,它看起来是这样的:
create table mdm.excel_lookup (
actual_part_number text not null,
excel_part_number text not null,
lookup_priority integer not null,
constraint excel_lookup_pk primary key (actual_part_number)
);
为了填充这个表,我使用plperl编写了一个函数,该函数试图获取任何给定的字符串,并预测Excel将如何将其搞乱。我相信我已经处理过带前导零和尾随零的数字,它们在小数点后被截断
不幸的是,这并不能涵盖一切。我不认为日期是可以预测的,所以我甚至可能不会尝试,除非有人有一个好主意。但是科学记数法呢?还有其他我没有想到的情况吗
我们的零件目录有150多万个零件,因此可能发生的情况有很多种可能性。如果我能抓住一个公平的百分比,我会很高兴
这是我迄今为止的职能。如果有人对我可以做些什么来捕获Excel可能做的其他事情有想法,我欢迎反馈。注意,到目前为止,这只处理我上面列出的场景
CREATE OR REPLACE FUNCTION excel_part(part_number text)
RETURNS text AS
$BODY$
my ($input) = @_;
if ($input =~ /[A-Za-z]/) {
return $input;
} elsif ($input =~ /^0+(\d+)$/) {
return $1;
} elsif ($input =~ /^(\d+\.\d*)0+$/) {
return $1 + 0;
} else {
return $input;
}
$BODY$
LANGUAGE plperl VOLATILE
COST 100;
另外,我没有和plperl结婚。我之所以使用它,是因为我知道Perl非常擅长文本处理。我的建议是将所有零件号提取到excel中,在完成编号后保存文件,然后将结果作为新表或原始表中的列上载回数据库。这样你就不必担心你没有处理的任何案件。如果您经常基于此进行查找,它还允许您对列进行索引,并且可以轻松地检测出任何零件号,这些零件号在经过筛选后最终会变成重复的零件号 在excel重新上传之前,您必须有一些方法来确定它们是什么。如果有一个代理Id列,你可以使用它,否则做一些简单的事情,比如在零件号前面加上零件号,这样excel就会看到一个字符串,而不会碰它
如果simbabque是正确的,并且不同的excel版本可以做不同的事情,您可以通过多个不同版本的excel运行此过程并保存唯一的munges。作为对Tim Tom回答的回应,这是一个C程序,它实现了他的建议。。。我觉得它很管用
NpgsqlConnection conn = new NpgsqlConnection();
conn.Open();
Excel.Application xl = new Excel.Application();
xl.Visible = true;
Excel.Workbook wb = xl.Workbooks.Add(1);
Excel.Worksheet ws = (Excel.Worksheet)wb.Sheets[1];
List<string> parts = new List<string>();
NpgsqlCommand cmd = new NpgsqlCommand("select prod_id from mdm.global_item_master",
conn);
NpgsqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
parts.Add(reader.GetString(0));
reader.Close();
NpgsqlCopyIn copy = new NpgsqlCopyIn(
"copy mdm.excel_item_id from STDIN WITH NULL AS '' CSV;", conn);
copy.Start();
NpgsqlCopySerializer cs = new NpgsqlCopySerializer(conn);
cs.Delimiter = ",";
foreach (string part in parts)
{
ws.Cells[1, 1].Value2 = part;
cs.AddString(part);
cs.AddString(ws.Cells[1, 1].Text);
cs.EndRow();
}
cs.Close();
copy.End();
conn.Close();
这些文件是CSV文件还是XLS文件?@simbabque-这是个好问题。它们以Excel本机文件的形式出现。我知道Excel也会发出非常好的CSV文件,但在这种情况下,在我们得到它之前就已经发出了声音。如果您可以为它们提供预设值,您可以修复单元格格式并锁定某些内容。这可能会有帮助。另外请注意,不同的本地版本的Excel会以不同的方式中断内容。主要问题是我们无法控制源代码。数据来自任何数量的来源,包括外部供应商和自动化作业。我们尽可能多地控制,但仍有电子表格是第二手、第三手、第四手的,我们无法追溯到原始版本。您必须将Excel和PostgreSQL表示转换为通用形式。e、 g.对于数字:将Excel和PostgreSQL中的零件号转换为固定精度的小数,并进行比较。你的函数必须处理科学记数法等。你将遇到的最大问题是一些白痴使用二进制浮点,所以你得到的是142.00199999部分,而不是142.002或其他任何部分。您需要某种形式的舍入,但如果您的零件号没有固定的小数位数限制,则这将很难实现。或者,如果他们可以有多个周期,我指的是不同的语言/国家版本,而不是版本。这是因为在不同的国家,用户输入的日期不同,小数点和逗号的处理也不同。那些有着独特魅力的东西。like 12.12将在德语Excel中转换为日期,尤其是导出到CSV时,将看起来像12。迪兹之类的。另一方面,在美国Excel中最有可能被视为文本的内容,但在德国Excel中它是一个浮点数。TimTom-一个非常简单的解决方案-仅供参考,我已经发布了我如何实际实现这一点以使其免费@simbabque-所有非常相关的要点;我们是全球性的,我可能必须找到一种方法,在不同的地区设置下运行这个程序,以确保我最大限度地正确修复每个部件。谢谢大家。