【问题标题】:Delphi: how to trim a excel rangeDelphi:如何修剪excel范围
【发布时间】:2025-12-07 21:55:02
【问题描述】:

虽然我是 * 的忠实粉丝,并且我找到了几个很好的解决方案,但这是我的第一个问题。 我正在编写一个 Delphitool(D6...旧但仍在工作!),以便更轻松地管理我们在学校的学生。

Delphi 读取一些(甚至更老的......)Visual Foxpro Dbase 表并在查询中收集所需的数据。此数据应导出到 Excel。 “理论上”一切正常,但我有几个问题:

  1. 查询字段填充有很多前导空格,这似乎 成为 FoxPro 问题(我发现了这个: http://www.ml-consult.co.uk/foxst-36.htm,不知道怎么操作 用它)
  2. 无法通过 sql 命令进行修剪(空格 由 foxpro 查询创建,表是“干净的”)
  3. 试图借助字段的“onGetText”方法在 Delphi 中完成任务 名称 - 这有帮助,但在数据集中,空格未受影响 (只有他们在网格中的字段值是正确的) - 也没有帮助 因为导出到 delphi 使用查询
  4. 所以我必须摆脱从 Delphi 到 Excel 的空白。我用这个: Exporting data from a DBGrid to Excel 并认为我可以执行 Excel 的修剪功能来操作 字段。所以我的问题是:如何执行 vba 代码?我找到了这个: Trim Cells using VBA in Excel

有什么想法吗?提前致谢!

PS: 我还寻找了一种简单的“替换所有空格但不在单词内”的方式,想到了正则表达式,但发现无法从我的 Delphi 代码中完成此操作。

由于 Excel 表中的文本不多(100 行,4 列),我可以遍历每个单元格……但这似乎不是很优雅。 How does Trim work in Excel VBA? How to trim text in a column with VBA - Excel

所以这里有简单替换所有空格的代码 - 不幸的是,它还替换了单元格中两个单词之间的必要空格:

 ovExcelApp := CreateOleObject('Excel.Application');
   try
   ovExcelApp.displayAlerts := false;
   ovExcelWorkbook := ovExcelApp.WorkBooks.Add;
   ovWS := ovExcelWorkbook.Worksheets.Item[1]; 
   ovWS.Activate;
   ovWS.Select;
   ovWS.Cells.NumberFormat := AnsiChar('@');
   ovRange := ovWS.Range['A1', 'A1']; //go to first cell
   ovRange.Resize[Data.RecordCount, Data.Fields.Count];
   ovRange.CopyFromRecordset(Data, Data.RecordCount, Data.Fields.Count); 
   ovExcelApp.Cells.Replace(
       What := ' ',
       Replacement := '', 
       LookAt := 2, 
       SearchOrder := 1, 
       MatchCase := False,
       SearchFormat := False,
       ReplaceFormat := False
       );
   end;
   // How could I do a regexp (only replace leading spaces) or do a trim over all cells withing ovWS?
   ovRange.EntireColumn.AutoFit;
   ovWS.SaveAs(DestName, 1, '', '', False, False);

尝试修剪字段值会导致错误:

procedure Tf_dbftools.qADO_einzelnAfterOpen(DataSet: TDataSet);
begin
  with qADO_einzeln do begin
    first;
    while not eof do begin
      edit;
      Fields[0].AsString := trim(fields[0].asstring);
      Fields[1].AsString := trim(fields[1].asstring);
      Fields[2].AsString := trim(fields[2].asstring);
      Fields[3].AsString := trim(fields[3].asstring);
      next;
    end;
    //post -> error
  end;
end;

我只需要在 qADO Query resp 中编辑数据(来自不同的表)。数据集以将内容正确导出到 Excel。我真的需要将数据复制到 clientDataset 来编辑它们吗?

【问题讨论】:

  • 当数据从 DBase 传输到 Excel 时,为什么不直接在 Delphi 代码中使用 trim()?
  • 谢谢你的回答,Jan。但是使用 CopyFromRecordset 方法,我只有一个 _Recordset 对象..我怎样才能访问字段值?
  • .. 尝试使用“AfterOpen”方法并执行一些 aodquery.edit 然后 Fields[0].asString := trim(Fields[0].asString.. adoquery.post...但没有帮助,无法将值写回查询中.. :-\
  • 是否可以在读取数据之前对 VFP 进行更新以清理数据?
  • @Hugh - 这怎么可能?我从这里microsoft.com/download/en/details.aspx?id=14839 下载了最新的 Foxpro 客户端 - 有没有办法禁用填充?另一方面:我只是在寻找一种在本地数据集中操作数据的方法(而不将其写回......所有找到的信息都涉及使用更新语句写回值。我只需要能够修剪字符串.. arrrrghhhh... ) 或在 Excel 中...

标签: excel delphi vba


【解决方案1】:

最后我通过手动复制每个单元格值选择了这个(简单...)解决方案,以便我可以使用 Delphi 的修剪功能:

.. 上面的一些代码,但现在“数据”是一个 TADOQuery:

 data.First;
    for RowIndex := 0 to Data.RecordCount - 1 do begin
      for ColumnIndex := 0 to data.Fields.Count - 1 do begin
        ovWS.Cells[RowIndex+1, ColumnIndex+1].Value := trim(data.Fields[columnIndex].AsString);

        next ;
      end;
    data.Next;
    next;

(......但仍然想知道是否有更简单和“更清洁”的方式......除了 Foxpro 中的填充太可怕了!)

【讨论】:

  • 另一种可能是为每个需要操作的字段创建一个计算字段 - 您可以将 trim 语句放入 OnCalcFields() 方法中。这意味着数据集将有每个数据的 2 个“版本”