预测Excel将如何使用Postgres函数解释字符串

时间:2015-09-03 15:02:37

标签: c# excel perl postgresql

在我的工作场所,我们有部件号(项目编号),当输入Excel时,经常会转换为Excel 认为用户的意思。

例如,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非常擅长文本处理。

2 个答案:

答案 0 :(得分:1)

我的建议是将所有零件编号提取到Excel,在文件完成整理后保存文件,然后将结果作为新表格(或原始表格中的列)上传回数据库。这样你就不必担心你没有处理的任何情况。如果你经常根据这一点进行查找,它还允许你索引列,并且可以轻松地检测出任何在被攻击后最终变成重复的部件号。

你必须有一些方法来确定他们在excel到达之前他们是什么,但重新上传。如果有一个代理Id列,你可以使用它,否则做一些简单的事情,比如在零件编号前添加“Part-”,这样excel就会看到一个字符串而不是触摸它。

如果simbabque是正确的并且不同的excel版本做不同的事情,你可以通过多个不同版本的excel运行这个过程并保存独特的munges。

答案 1 :(得分:0)

回应蒂姆汤姆的回答,这是一个实施他的建议的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();