unit main;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Vcl.StdCtrls, Vcl.ExtCtrls, DB, PostgreSQLUniProvider, Uni, MemDS, DBAccess,
GridsEh, DBGridEh, DBGridEhGrouping, ToolCtrlsEh, DBGridEhToolCtrls, DynVarsEh,
EhLibVCL, Vcl.Buttons, Vcl.ComCtrls, Vcl.Menus, Vcl.DBCtrls, Vcl.Mask,
IdTCPClient, DBAxisGridsEh, DBGridEhImpExp, DBCtrlsEh, DataSetImpExpEh,
System.UITypes, ShellAPI,Vcl.Clipbrd, SynEditHighlighter, SynHighlighterSQL,
SynAutoCorrect, SynCompletionProposal, SynEdit, SynMemo,SynEditTypes;
type
TForm1 = class(TForm)
Panel1: TPanel;
Label1: TLabel;
cbConnections: TComboBox;
Label2: TLabel;
btnExecute: TButton;
Panel2: TPanel;
DBGridEh0: TDBGridEh;
UniConnection0: TUniConnection;
UniQuery1: TUniQuery;
btnUpdate: TButton;
btnExportExcel: TButton;
SaveDialog1: TSaveDialog;
StatusBar1: TStatusBar;
btnExit1: TButton;
UniDataSource0: TUniDataSource;
lstTables: TListBox; // 新增列表控件
// DBGridEh1: TDBGridEh; // 新增DBGridEh控件
UniQueryTables: TUniQuery; // 用于获取表信息的查询
UniQueryFields: TUniQuery; // 用于获取字段信息的查询
UniDataSource1: TUniDataSource;
DBGridEh1: TDBGridEh;
pmTables: TPopupMenu;
SynCompletionProposal1: TSynCompletionProposal;
SynAutoComplete1: TSynAutoComplete;
SynAutoCorrect1: TSynAutoCorrect;
SynEdit1: TSynEdit;
SynSQLSyn1: TSynSQLSyn; // 新增数据源
procedure FormCreate(Sender: TObject);
procedure btnExecuteClick(Sender: TObject);
procedure btnUpdateClick(Sender: TObject);
procedure btnExportExcelClick(Sender: TObject);
procedure cbConnectionsChange(Sender: TObject);
procedure btnExit1Click(Sender: TObject);
procedure lstTablesClick(Sender: TObject);
procedure SynCompletionProposal1Execute(Kind: SynCompletionType;
Sender: TObject; var CurrentInput: string; var x, y: Integer;
var CanExecute: Boolean);
procedure SynEdit1DblClick(Sender: TObject);
procedure SynEdit1KeyPress(Sender: TObject; var Key: Char);
private
{ Private declarations }
procedure LoadConnections;
procedure ConnectToDatabase(Index: Integer);
procedure LoadTables; // 加载所有表
procedure LoadFields(const TableFullName: string); // 加载选定表的所有字段
function TestNetworkConnection(const Server: string; Port: Integer): Boolean;
procedure lstTablesContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
procedure DBGridEh1ContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
procedure CopyTableNameToClipboard(Sender: TObject);
procedure CopyFieldNameToClipboard(Sender: TObject);
procedure InitHighlighter;
procedure LoadDatabaseSchema;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
ExcelXP, ComObj;
function TForm1.TestNetworkConnection(const Server: string; Port: Integer): Boolean;
var
Client: TIdTCPClient;
begin
Result := False;
Client := TIdTCPClient.Create(nil);
try
Client.Host := Server;
Client.Port := Port;
try
Client.Connect;
Result := Client.Connected;
Client.Disconnect;
except
Result := False;
end;
finally
Client.Free;
end;
end;
procedure TForm1.lstTablesContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
var
ItemIndex: Integer;
TableName: string;
MenuItem: TMenuItem;
begin
// 获取当前鼠标位置对应的项索引
ItemIndex := lstTables.ItemAtPos(MousePos, True);
if ItemIndex >= 0 then
begin
lstTables.ItemIndex := ItemIndex;
TableName := lstTables.Items[ItemIndex];
// 清空现有菜单项
pmTables.Items.Clear;
// 创建新的菜单项
MenuItem := TMenuItem.Create(pmTables);
MenuItem.Caption := '复制表名: ' + TableName;
MenuItem.OnClick := CopyTableNameToClipboard;
pmTables.Items.Add(MenuItem);
// 显示弹出菜单
pmTables.Popup(MousePos.X + lstTables.Left, MousePos.Y + lstTables.Top);
Handled := True; // 阻止默认的弹出菜单
end;
end;
procedure TForm1.SynCompletionProposal1Execute(Kind: SynCompletionType;
Sender: TObject; var CurrentInput: string; var x, y: Integer;
var CanExecute: Boolean);
var
FieldsQuery: TUniQuery;
SchemaName, TableName, CurrentWord, FullTableName: string;
DotPos, LastDotPos, StartPos: Integer;
CaretPos: TBufferCoord;
LineText: string;
begin
CanExecute := UniConnection0.Connected;
if not CanExecute then Exit;
// 外层更新控制 - 确保整个操作原子性
SynCompletionProposal1.ItemList.BeginUpdate;
try
SynCompletionProposal1.ItemList.Clear; // 先清空列表
try
// 获取当前光标位置
CaretPos := SynEdit1.CaretXY;
// 获取当前行的文本
if CaretPos.Line > 0 then
LineText := SynEdit1.Lines[CaretPos.Line - 1]
else
LineText := '';
// 从光标位置向前查找,获取完整的单词(包括点号)
StartPos := CaretPos.Char;
while (StartPos > 1) and (StartPos <= Length(LineText)) and
(LineText[StartPos - 1] in ['a'..'z', 'A'..'Z', '0'..'9', '_', '.']) do
Dec(StartPos);
if StartPos <= Length(LineText) then
CurrentWord := Copy(LineText, StartPos, CaretPos.Char - StartPos)
else
CurrentWord := '';
// 查找最后一个点号的位置
LastDotPos := LastDelimiter('.', CurrentWord);
if LastDotPos = 0 then
begin
// 没有点号,显示所有表名
LoadDatabaseSchema;
end
else
begin
// 有点号,检查点号是否在末尾(表示需要字段提示)
if LastDotPos = Length(CurrentWord) then
begin
// 点号在末尾,获取模式名和表名
FullTableName := Copy(CurrentWord, 1, LastDotPos - 1);
// 解析模式名和表名
DotPos := LastDelimiter('.', FullTableName);
if DotPos > 0 then
begin
SchemaName := Copy(FullTableName, 1, DotPos - 1);
TableName := Copy(FullTableName, DotPos + 1, Length(FullTableName) - DotPos);
end
else
begin
SchemaName := 'public'; // 默认模式
TableName := FullTableName;
end;
// 验证表名和模式名不为空
if (Trim(TableName) = '') or (Trim(SchemaName) = '') then
begin
SynCompletionProposal1.ItemList.Add('(无字段)');
Exit;
end;
FieldsQuery := TUniQuery.Create(nil);
try
FieldsQuery.Connection := UniConnection0;
FieldsQuery.SQL.Text :=
'SELECT column_name ' +
'FROM information_schema.columns ' +
'WHERE LOWER(table_name) = LOWER(:table_name) ' +
'AND LOWER(table_schema) = LOWER(:schema_name) ' +
'ORDER BY ordinal_position';
FieldsQuery.ParamByName('table_name').AsString := TableName;
FieldsQuery.ParamByName('schema_name').AsString := SchemaName;
FieldsQuery.Open;
if FieldsQuery.RecordCount = 0 then
begin
// 添加占位项防止空列表
SynCompletionProposal1.ItemList.Add('(无字段)');
end
else
begin
while not FieldsQuery.Eof do
begin
SynCompletionProposal1.ItemList.Add(
FieldsQuery.FieldByName('column_name').AsString
);
FieldsQuery.Next;
end;
end;
finally
FieldsQuery.Free;
end;
end
else
begin
// 点号不在末尾,显示表名提示
LoadDatabaseSchema;
end;
end;
except
on E: Exception do
begin
SynCompletionProposal1.ItemList.Add('错误: ' + E.Message);
end;
end;
// 确保列表不为空
if SynCompletionProposal1.ItemList.Count = 0 then
SynCompletionProposal1.ItemList.Add('(无建议)');
finally
SynCompletionProposal1.ItemList.EndUpdate; // 确保总是结束更新
end;
end;
procedure TForm1.SynEdit1DblClick(Sender: TObject);
begin
SynEdit1.SelectAll;
end;
procedure TForm1.SynEdit1KeyPress(Sender: TObject; var Key: Char);
begin
// 当输入点号时触发自动完成
if Key = '.' then
begin
if not UniConnection0.Connected then
begin
ShowMessage('数据库未连接');
Key := #0;
Exit;
end;
// 先插入点号
SynEdit1.SelText := '.';
// 立即触发自动完成
SynCompletionProposal1.ActivateCompletion;
Key := #0; // 阻止默认处理
end
// Ctrl+Space 触发自动完成
else if (Key = ' ') and (GetKeyState(VK_CONTROL) < 0) then
begin
Key := #0;
SynCompletionProposal1.ActivateCompletion;
end;
end;
procedure TForm1.InitHighlighter;
begin
SynSQLSyn1.SQLDialect := sqlPostgres;
SynSQLSyn1.KeyAttri.Foreground := clNavy;
SynSQLSyn1.CommentAttri.Foreground := clGreen;
SynSQLSyn1.StringAttri.Foreground := clMaroon;
SynEdit1.Highlighter := SynSQLSyn1;
SynEdit1.Options := SynEdit1.Options + [eoAutoIndent, eoScrollPastEol];
end;
procedure TForm1.DBGridEh1ContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
var
AHitTest: TGridCoord; // 使用 TGridCoord 替代 TGridHitTestInfoEh
FieldName: string;
MenuItem: TMenuItem;
Cell: TGridCoord;
begin
// 获取鼠标点击位置的单元格坐标
Cell := DBGridEh1.MouseCoord(MousePos.X, MousePos.Y);
if (Cell.X >= 0) and (Cell.Y >= 0) and (UniQueryFields.Active) and
(not UniQueryFields.IsEmpty) and (Cell.X = 0) then // column_name 列
begin
// 定位到对应行
UniQueryFields.RecNo := Cell.Y + 1;
FieldName := UniQueryFields.FieldByName('column_name').AsString;
// 清空现有菜单项
pmTables.Items.Clear;
// 创建新的菜单项
MenuItem := TMenuItem.Create(pmTables);
MenuItem.Caption := '复制字段名: ' + FieldName;
MenuItem.OnClick := CopyFieldNameToClipboard;
pmTables.Items.Add(MenuItem);
// 显示弹出菜单
pmTables.Popup(MousePos.X + DBGridEh1.Left, MousePos.Y + DBGridEh1.Top);
Handled := True; // 阻止默认的弹出菜单
end;
end;
procedure TForm1.LoadDatabaseSchema;
var
TablesQuery: TUniQuery;
begin
if not UniConnection0.Connected then
begin
OutputDebugString('数据库未连接');
Exit;
end;
try
TablesQuery := TUniQuery.Create(nil);
try
TablesQuery.Connection := UniConnection0;
TablesQuery.SQL.Text :=
'SELECT table_schema, table_name ' +
'FROM information_schema.tables ' +
'WHERE table_catalog = current_database() ' +
'AND table_schema NOT IN (''information_schema'', ''pg_catalog'') ' +
'AND table_type = ''BASE TABLE'' ' +
'ORDER BY table_schema, table_name';
TablesQuery.Open;
// 注意:这里直接添加,因为外层已经BeginUpdate
while not TablesQuery.Eof do
begin
SynCompletionProposal1.ItemList.Add(
TablesQuery.FieldByName('table_schema').AsString + '.' +
TablesQuery.FieldByName('table_name').AsString
);
TablesQuery.Next;
end;
finally
TablesQuery.Free;
end;
except
on E: Exception do
begin
SynCompletionProposal1.ItemList.Add('加载架构失败: ' + E.Message);
OutputDebugString(PChar('架构加载错误: ' + E.ClassName + ' - ' + E.Message));
end;
end;
end;
procedure TForm1.CopyTableNameToClipboard(Sender: TObject);
var
TableName: string;
begin
if lstTables.ItemIndex >= 0 then
begin
TableName := lstTables.Items[lstTables.ItemIndex];
Clipboard.AsText := TableName;
StatusBar1.Panels[0].Text := '已复制表名: ' + TableName;
end;
end;
procedure TForm1.CopyFieldNameToClipboard(Sender: TObject);
var
FieldName: string;
begin
if UniQueryFields.Active and not UniQueryFields.IsEmpty then
begin
FieldName := UniQueryFields.FieldByName('column_name').AsString;
Clipboard.AsText := FieldName;
StatusBar1.Panels[0].Text := '已复制字段名: ' + FieldName;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
LoadConnections;
if cbConnections.Items.Count > 0 then
begin
cbConnections.ItemIndex := 0;
// 尝试连接
ConnectToDatabase(0);
end;
// 修改自动完成设置
SynCompletionProposal1.Options := [scoLimitToMatchedText, scoUseInsertList, scoEndCharCompletion];
SynCompletionProposal1.EndOfTokenChr := ' .()=,;';
SynCompletionProposal1.TriggerChars := '.'; // 点号触发
SynCompletionProposal1.ShortCut := 16416; // Ctrl+Space
LoadTables; // 加载所有表
// 创建弹出菜单实例(如果设计时没有创建)
if not Assigned(pmTables) then
pmTables := TPopupMenu.Create(Self);
// 关联右键菜单事件
lstTables.OnContextPopup := lstTablesContextPopup;
DBGridEh1.OnContextPopup := DBGridEh1ContextPopup;
InitHighlighter;
//在FormCreate中添加键盘事件
SynEdit1.OnKeyPress := SynEdit1KeyPress;
end;
procedure TForm1.LoadConnections;
begin
cbConnections.Items.Clear;
cbConnections.Items.Add('连接1: 21 gy_zh_hy_cp_aq_jf_yw_yy_nl_dt_dz_auth_td_gz');
cbConnections.Items.Add('连接2: 22 sc_fz_wd_sz_bi_jk_hl_ys_tj');
cbConnections.Items.Add('连接3: 23 jy_jc_bl_zj');
cbConnections.Items.Add('连接4: 24 jz_br_yj');
cbConnections.Items.Add('连接5: 25 yz_lj_hz_zz_yx');
cbConnections.Items.Add('连接6: 26 fy_yg_hg_wm');
cbConnections.Items.Add('连接7: 27 yp_zl_sm_jh_wl');
cbConnections.Items.Add('连接8: 28 聚合库');
end;
procedure TForm1.LoadTables;
begin
lstTables.Items.Clear;
if not UniConnection0.Connected then
Exit;
try
UniQueryTables.Close;
// 修改SQL查询,获取lyradb数据库中除public模式外的所有表
UniQueryTables.SQL.Text :=
'SELECT table_schema, table_name ' +
'FROM information_schema.tables ' +
'WHERE table_catalog = ''lyradb'' ' + // 指定数据库名
'AND table_schema NOT IN (''public'', ''information_schema'', ''pg_catalog'',''hint_plan'',''lyra'',''profile'',''repack'',''util'') ' + // 排除系统模式
'AND table_schema NOT LIKE ''ceti%'' ' +// 排除系统模式
'AND table_schema NOT LIKE ''grus%'' ' +// 排除系统模式
'AND table_type = ''BASE TABLE'' ' + // 只获取基本表
'ORDER BY table_schema, table_name';
UniQueryTables.Open;
while not UniQueryTables.Eof do
begin
// 显示格式:模式名.表名
lstTables.Items.Add(
UniQueryTables.FieldByName('table_schema').AsString + '.' +
UniQueryTables.FieldByName('table_name').AsString
);
UniQueryTables.Next;
end;
UniQueryTables.Close;
except
on E: Exception do
ShowMessage('加载表列表失败: ' + E.Message);
end;
end;
procedure TForm1.lstTablesClick(Sender: TObject);
begin
if lstTables.ItemIndex >= 0 then
begin
// 加载选定表的所有字段
LoadFields(lstTables.Items[lstTables.ItemIndex]);
end;
end;
procedure TForm1.LoadFields(const TableFullName: string);
var
SchemaName, TableName: string;
DotPos,i: Integer;
begin
// 解析模式名和表名
DotPos := Pos('.', TableFullName);
if DotPos > 0 then
begin
SchemaName := AnsiQuotedStr(Copy(TableFullName, 1, DotPos-1), '"');
TableName := AnsiQuotedStr(Copy(TableFullName, DotPos+1, MaxInt), '"');
end
else
begin
SchemaName := 'public'; // 默认模式
TableName := AnsiQuotedStr(TableFullName, '"');
end;
// 清空字段信息
DBGridEh1.Columns.Clear;
// 获取选定表的所有字段信息(包含注释)
UniQueryFields.Close;
UniQueryFields.SQL.Text :=
'SELECT ' +
' c.column_name, ' +
' c.data_type, ' +
' c.column_default, ' +
' c.is_nullable, ' +
' col_description((c.table_schema||''.''||c.table_name)::regclass::oid, c.ordinal_position) as column_comment ' +
'FROM information_schema.columns c ' +
'WHERE c.table_schema = ' + SchemaName +
'AND c.table_name = ' + TableName +
'ORDER BY c.ordinal_position';
UniQueryFields.ParamByName('schema_name').AsString := SchemaName;
UniQueryFields.ParamByName('table_name').AsString := TableName;
UniQueryFields.Open;
// 设置数据源
UniDataSource1.DataSet := UniQueryFields;
// 自动添加所有列到DBGridEh
DBGridEh1.Columns.AddAllColumns(True);
// 然后再限制最大宽度
for i := 0 to DBGridEh1.Columns.Count - 1 do
begin
DBGridEh1.Columns[i].OptimizeWidth;
if DBGridEh1.Columns[i].Width > 200 then
DBGridEh1.Columns[i].Width := 200;
end;
end;
procedure TForm1.ConnectToDatabase(Index: Integer);
var
ConnStr: string;
begin
UniConnection0.Disconnect;
// 设置 Provider 名称
UniConnection0.ProviderName := 'PostgreSQL';
case Index of
0:
begin // 连接1
UniConnection0.Server := '192.168.129.21';
UniConnection0.Database := 'lyradb';
UniConnection0.Username := 'lyra_ops';
UniConnection0.Password := 'i48VF69KXwgP';
UniConnection0.Port := 5432; // 明确指定端口
end;
1:
begin // 连接2
UniConnection0.Server := '192.168.129.22';
UniConnection0.Database := 'lyradb';
UniConnection0.Username := 'lyra_ops';
UniConnection0.Password := 'i48VF69KXwgP';
UniConnection0.Port := 5432; // 明确指定端口
end;
// 其他连接配置...
2:
begin // 连接3
UniConnection0.Server := '192.168.129.23';
UniConnection0.Database := 'lyradb';
UniConnection0.Username := 'lyra_ops';
UniConnection0.Password := 'i48VF69KXwgP';
UniConnection0.Port := 5432; // 明确指定端口
end;
3:
begin // 连接4
UniConnection0.Server := '192.168.129.24';
UniConnection0.Database := 'lyradb';
UniConnection0.Username := 'lyra_ops';
UniConnection0.Password := 'i48VF69KXwgP';
UniConnection0.Port := 5432; // 明确指定端口
end;
4:
begin // 连接5
UniConnection0.Server := '192.168.129.25';
UniConnection0.Database := 'lyradb';
UniConnection0.Username := 'lyra_ops';
UniConnection0.Password := 'i48VF69KXwgP';
UniConnection0.Port := 5432; // 明确指定端口
end;
5:
begin // 连接6
UniConnection0.Server := '192.168.129.26';
UniConnection0.Database := 'lyradb';
UniConnection0.Username := 'lyra_ops';
UniConnection0.Password := 'i48VF69KXwgP';
UniConnection0.Port := 5432; // 明确指定端口
end;
6:
begin // 连接7
UniConnection0.Server := '192.168.129.27';
UniConnection0.Database := 'lyradb';
UniConnection0.Username := 'lyra_ops';
UniConnection0.Password := 'i48VF69KXwgP';
UniConnection0.Port := 5432; // 明确指定端口
end;
7:
begin // 连接8
UniConnection0.Server := '192.168.129.28';
UniConnection0.Database := 'lyradb';
UniConnection0.Username := 'lyra_ops';
UniConnection0.Password := 'i48VF69KXwgP';
UniConnection0.Port := 5432; // 明确指定端口
end;
end;
// 显示连接字符串用于调试
ConnStr := Format('Server=%s;Database=%s;User_ID=%s;Port=%d', [UniConnection0.Server, UniConnection0.Database, UniConnection0.Username, UniConnection0.Port]);
StatusBar1.Panels[0].Text := '正在连接: ' + ConnStr;
try
if not TestNetworkConnection(UniConnection0.Server, 5432) then
begin
ShowMessage('无法连接到数据库服务器,请检查网络连接');
Exit;
end;
UniConnection0.Connect;
// 在状态栏显示连接状态
StatusBar1.Panels[0].Text := '已连接到: ' + cbConnections.Items[Index];
// 连接成功后加载表
// 连接成功后重新加载
LoadTables;
if UniConnection0.Connected then
begin
// 清空并重新加载表名缓存
SynCompletionProposal1.ItemList.Clear;
LoadDatabaseSchema;
end;
except
on E: Exception do
// ShowMessage('连接失败: ' + E.Message);
begin
ShowMessage(Format('连接失败:'#13#10'错误: %s'#13#10'连接字符串: %s', [E.Message, ConnStr]));
StatusBar1.Panels[0].Text := '连接失败';
end;
end;
end;
procedure TForm1.btnExecuteClick(Sender: TObject);
var
i: Integer;
SQLToExecute: string;
begin
if not UniConnection0.Connected then
begin
ShowMessage('请先连接到数据库');
Exit;
end;
// 判断是否有选中文本
if SynEdit1.SelText <> '' then
SQLToExecute := SynEdit1.SelText // 执行选中的SQL
else
SQLToExecute := SynEdit1.Text; // 执行全部SQL
if Trim(SQLToExecute) = '' then
begin
ShowMessage('请输入SQL语句');
Exit;
end;
try
UniQuery1.Close;
UniQuery1.SQL.Text := SQLToExecute;
// 判断SQL类型(查询或更新)
if (Pos('SELECT', UpperCase(SQLToExecute)) = 1) or
(Pos('WITH', UpperCase(SQLToExecute)) = 1) or
(Pos('SHOW', UpperCase(SQLToExecute)) = 1) then
begin
UniQuery1.Open;
StatusBar1.Panels[1].Text := '记录数: ' + IntToStr(UniQuery1.RecordCount);
// 自动调整列宽
DBGridEh0.Columns.Clear;
DBGridEh0.Columns.AddAllColumns(True);
for i := 0 to DBGridEh0.Columns.Count - 1 do
begin
DBGridEh0.Columns[i].OptimizeWidth;
if DBGridEh0.Columns[i].Width > 200 then
DBGridEh0.Columns[i].Width := 200;
end;
end
else
begin
// 执行非查询语句
UniQuery1.ExecSQL;
StatusBar1.Panels[1].Text := '执行成功,影响行数: ' + IntToStr(UniQuery1.RowsAffected);
end;
except
on E: Exception do
ShowMessage('执行SQL失败: ' + E.Message);
end;
end;
procedure TForm1.btnUpdateClick(Sender: TObject);
begin
if UniQuery1.State in [dsEdit, dsInsert] then
UniQuery1.Post;
try
UniQuery1.ApplyUpdates;
ShowMessage('更新成功');
except
on E: Exception do
ShowMessage('更新失败: ' + E.Message);
end;
end;
procedure TForm1.btnExportExcelClick(Sender: TObject);
var
// ExpClass: TDBGridEhExportClass;
Exp: TDBGridEhExportAsXLSX;
Ext: string;
i: Integer;
SaveDialog1: TSaveDialog;
begin
if UniQuery1.IsEmpty then
begin
ShowMessage('没有数据可导出');
Exit;
end;
SaveDialog1 := TSaveDialog.Create(nil);
try
SaveDialog1.Filter := 'Excel文件(*.xls)|*.xls|Excel 2007+(*.xlsx)|*.xlsx';
SaveDialog1.DefaultExt := 'xls';
SaveDialog1.InitialDir := '\Desktop\';
SaveDialog1.FileName := '导出数据_' + FormatDateTime('yyyymmddhhnnss', Now);
if SaveDialog1.Execute then
begin
// ExpClass := TDBGridEhExportAsXLS;
Exp := TDBGridEhExportAsXLSX.Create;
Ext := 'xls';
if Pos('.xlsx', LowerCase(SaveDialog1.FileName)) > 0 then
Ext := 'xlsx';
if UpperCase(ExtractFileExt(SaveDialog1.FileName)) <> '.' + UpperCase(Ext) then
SaveDialog1.FileName := SaveDialog1.FileName + '.' + Ext;
// 执行导出
try
// 设置DBGridEh的样式
Exp.DBGridEh := DBGridEh0;
Exp.DBGridEh.TitleFont := DBGridEh0.TitleFont;
Exp.DBGridEh.TitleFont.Name := '宋体';
Exp.DBGridEh.TitleFont.Style := [fsBold];
Exp.DBGridEh.TitleFont.Size := 12;
Exp.DBGridEh.TitleParams.Color := clSkyBlue;
for i := 0 to Exp.DBGridEh.Columns.Count - 1 do
begin
Exp.DBGridEh.Columns[i].OptimizeWidth;
if Exp.DBGridEh.Columns[i].Width > 200 then
Exp.DBGridEh.Columns[i].Width := 200;
end;
if SameText(Ext, 'xlsx') then
begin
Exp.ExportToFile(SaveDialog1.FileName, True);
end
else
begin
Exp.ExportToFile(SaveDialog1.FileName, True);
end;
finally
Exp.Free;
end;
// ShowMessage('导出成功: ' + SaveDialog1.FileName);
// 假设导出操作已经完成
if MessageDlg('导出成功: ' + SaveDialog1.FileName + #13#10'是否要打开文件?', mtInformation, [mbYes, mbNo], 0, mbNo) = mrYes then
begin
// 用户点击了"是"(打开文件)
ShellExecute(0, 'open', PChar(SaveDialog1.FileName), nil, nil, SW_SHOWNORMAL);
end;
end;
finally
SaveDialog1.Free;
end;
end;
procedure TForm1.btnExit1Click(Sender: TObject);
begin
Form1.Close;
end;
procedure TForm1.cbConnectionsChange(Sender: TObject);
begin
ConnectToDatabase(cbConnections.ItemIndex);
end;
end.
按意见修改代码如上,但录入“.”时还会提示“List index out of bounds (0)”,麻烦彻底查一下原因,到底要怎么改?
最新发布