【发布时间】:2014-07-12 22:54:55
【问题描述】:
我正在关注this tutorial 将 CSV 文件导入 Delphi。我起草了下面提供的代码。程序编译没有问题,但是当我尝试执行函数来读取文件时,我得到 grid out of range 错误消息。
unit geoimp;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.Buttons, Vcl.StdCtrls,
Vcl.Grids, Vcl.DBGrids, Data.DB, Datasnap.DBClient;
const
shfolder = 'ShFolder.dll';
type
TMainForm = class(TForm)
MainPageControl: TPageControl;
ImportTab: TTabSheet;
MapPreviewTab: TTabSheet;
GeoMatchingTab: TTabSheet;
ImportLbl: TLabel;
SlctImportDta: TSpeedButton;
MainOpenDialog: TOpenDialog;
MainListBox: TListBox;
SG1: TStringGrid;
procedure SlctImportDtaClick(Sender: TObject);
private
{ Private declarations }
procedure ParseRecord(sRecord: string; Row: integer);
procedure ReadCSVFile;
public
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
{$R *.dfm}
procedure TMainForm.ParseRecord(sRecord: string; Row: integer);
var
Col, PosComma: integer;
sField: string;
begin
sRecord := StringReplace(sRecord, '"', '',
[rfReplaceAll] ); // 1.
Col := 0; // first column of stringgrid
repeat
PosComma := Pos(',', sRecord); // 2.
if PosComma > 0 then
sField := Copy(sRecord, 1, PosComma - 1) // 3.a
else
sField := sRecord; // 3.b
SG1.Cells[Col, Row] := sField; // 4.
if PosComma > 0 then begin // 5.
Delete(sRecord, 1, PosComma);
Col := Col + 1; // next column
end;
until PosComma = 0; // 6.
end;
procedure TMainForm.ReadCSVFile;
var
FileName1, sRecord: string;
Row: integer;
begin
FileName1 := MainOpenDialog.FileName;
MainListBox.Items.LoadFromFile(FileName1);
SG1.RowCount := MainListBox.Items.Count;
for Row := 0 to MainListBox.Items.Count - 1 do begin
sRecord := MainListBox.Items[Row];
ParseRecord(sRecord, Row);
end;
// 5. Select first "data" cell
SG1.Row := 1;
SG1.Col := 0;
SG1.SetFocus;
end;
procedure TMainForm.SlctImportDtaClick(Sender: TObject);
begin
// Create the open dialog object - assign to our open dialog variable
MainOpenDialog := TOpenDialog.Create(self);
// Set up the starting directory to be the current one
MainOpenDialog.InitialDir := GetCurrentDir;
// Only allow existing files to be selected
MainOpenDialog.Options := [ofFileMustExist];
// Allow only .dpr and .pas files to be selected
MainOpenDialog.Filter :=
'CSV Files|*.csv';
// Select pascal files as the starting filter type
MainOpenDialog.FilterIndex := 2;
// Display the open file dialog
if MainOpenDialog.Execute
then ReadCSVFile
else ShowMessage('Open file was cancelled');
// Free up the dialog
MainOpenDialog.Free;
end;
end.
【问题讨论】:
-
你把 StringGrid(行和列)做了多大? CSV 文件中有多少行和多少列数据?
-
@David Schwartz 给了你一个很好的答案。更一般地说,在编写代码时养成预测问题的习惯是一个好主意,例如“我的 Col 值是否会访问我的网格中的有效列,如果不能访问,我该怎么办。”你知道他们说什么:“期待意外。”
-
通过使用
StringReplace(..., [rfReplaceAll])来处理Char(和其他东西)来判断本教程是有缺陷的。你看到TStrings.CommaText了吗? (只记得StrictDelimiter)
标签: class delphi csv import tstringgrid