📄 qimport3common.pas
字号:
i := -1;
tmp := Copy(S, 2, Length(S) - 1);
try
i := StrToInt(tmp);
except
end;
if i > -1 then Result := Chr(i);
end;
end;
function PadString(const S: string; Chr: char; Len: integer): string;
var
i: integer;
begin
Result := S;
if Length(S) >= Len then Exit;
for i := Length(S) to Len do
Result := Result + Chr;
end;
function Char2Str(Chr: char): string;
begin
if Chr in [#33..#127]
then Result := Chr
else Result := Format('#%d', [Ord(Chr)]);
end;
function Str2Char(const Str: string; Default: char): char;
begin
Result := Default;
if Str <> EmptyStr then
begin
if Length(Str) = 1 then Result := Str[1]
else if Str[1] = '#'
then Result := Chr(StrToIntDef(Copy(Str, 2, Length(Str)), 0));
end;
end;
{$IFNDEF NOGUI}
procedure GridDrawCell(Grid: {$IFDEF QI_UNICODE}TEmsWideStringGrid{$ELSE}TStringGrid{$ENDIF};
const SheetName: string; SheetNumber, ACol, ARow: integer; Rect: TRect;
State: TGridDrawState; DefinedRanges: TMapRow; SkipCols, SkipRows: integer;
IsEditing: boolean; Selection: TMapRow);
var
X, Y, i: integer;
CellNeighbours: TCellNeighbours;
begin
if gdFixed in State then
begin
X := Rect.Left + (Rect.Right - Rect.Left - Grid.{$IFDEF QI_UNICODE}Canvas.TextWidthW{$ELSE}Canvas.TextWidth{$ENDIF}(Grid.Cells[ACol, ARow])) div 2;
Y := Rect.Top + (Rect.Bottom - Rect.Top - Grid.{$IFDEF QI_UNICODE}Canvas.TextHeightW{$ELSE}Canvas.TextHeight{$ENDIF}(Grid.Cells[ACol, ARow])) div 2;
if ((ACol = Grid.Col) and (ARow = 0)) or
((ARow = Grid.Row) and (ACol = 0)) then
begin
Grid.Canvas.Font.Style := Grid.Canvas.Font.Style + [fsBold];
Grid.Canvas.Font.Color := clHighlightText;
Grid.Canvas.Brush.Color := clBtnShadow;
end
else begin
Grid.Canvas.Font.Style := Grid.Canvas.Font.Style - [fsBold];
Grid.Canvas.Font.Color := clWindowText;
Grid.Canvas.Brush.Color := clBtnFace;
end;
Grid.Canvas.FillRect(Rect);
Grid.{$IFDEF QI_UNICODE}Canvas.TextOutW{$ELSE}Canvas.TextOut{$ENDIF}(X, Y + 1, Grid.Cells[ACol, ARow]);
Exit;
end;
if (gdSelected in State) and not (gdFocused in State) then
begin
Grid.DefaultDrawing := false;
Grid.Canvas.Brush.Color := clWindow;
Grid.Canvas.FillRect(Rect);
Grid.Canvas.Font.Color := clWindowText;
Grid.{$IFDEF QI_UNICODE}Canvas.TextRectW{$ELSE}Canvas.TextRect{$ENDIF}(Rect, Rect.Left + 2, Rect.Top + 2,
Grid.Cells[ACol, ARow]);
DrawFocusRect(Grid.Canvas.Handle, Rect);
end;
if not IsEditing then
begin
for i := 0 to DefinedRanges.Count - 1 do
begin
if not (gdFixed in State) and (DefinedRanges.Count > 0) and Assigned(Grid.Parent) and
CellInRange(DefinedRanges[i], SheetName, SheetNumber, ACol, ARow) and
{((Range <> Range.MapRow[0]) or}
(((SkipRows = 0) or (ARow > SkipRows)) and
((SkipCols = 0) or (ACol > SkipCols))){)} then
begin
Grid.Canvas.Brush.Color := 12639424;
Grid.Canvas.FillRect(Rect);
Grid.{$IFDEF QI_UNICODE}Canvas.TextRectW{$ELSE}Canvas.TextRect{$ENDIF}(Rect, Rect.Left + 2, Rect.Top + 2, Grid.Cells[ACol, ARow]);
if (gdSelected in State) and not (gdFocused in State) then
begin
DrawFocusRect(Grid.Canvas.Handle, Rect);
end;
Grid.Canvas.Pen.Color := clGreen;
Grid.Canvas.Pen.Width := 3;
CellNeighbours := GetCellNeighbours(DefinedRanges, SheetName,
SheetNumber, ACol, ARow);
case DefinedRanges[i].RangeType of
rtCol: begin
if not (cnLeft in CellNeighbours) then
begin
Grid.Canvas.MoveTo(Rect.Left, Rect.Top);
Grid.Canvas.LineTo(Rect.Left, Rect.Bottom);
end;
if not (cnRight in CellNeighbours) then
begin
Grid.Canvas.MoveTo(Rect.Right - 1, Rect.Top);
Grid.Canvas.LineTo(Rect.Right - 1, Rect.Bottom);
end;
if ((DefinedRanges[i].Direction = rdDown) and (DefinedRanges[i].Col1 > 0) and
(DefinedRanges[i].Row1 > 0) and (DefinedRanges[i].Col1 = ACol) and
(DefinedRanges[i].Row1 = ARow)) or
((DefinedRanges[i].Direction = rdUp) and (DefinedRanges[i].Col2 > 0) and
(DefinedRanges[i].Row2 > 0) and (DefinedRanges[i].Col2 = ACol) and
(DefinedRanges[i].Row2 = ARow)) then
begin
if not (cnTop in CellNeighbours) then
begin
Grid.Canvas.MoveTo(Rect.Left, Rect.Top);
Grid.Canvas.LineTo(Rect.Right, Rect.Top);
end;
end
else if ((DefinedRanges[i].Direction = rdDown) and (DefinedRanges[i].Col2 > 0) and
(DefinedRanges[i].Row2 > 0) and (DefinedRanges[i].Col2 = ACol) and
(DefinedRanges[i].Row2 = ARow)) or
((DefinedRanges[i].Direction = rdUp) and (DefinedRanges[i].Col1 > 0) and
(DefinedRanges[i].Row1 > 0) and (DefinedRanges[i].Col1 = ACol) and
(DefinedRanges[i].Row1 = ARow)) then
begin
if not (cnBottom in CellNeighbours) then
begin
Grid.Canvas.MoveTo(Rect.Left, Rect.Bottom - 1);
Grid.Canvas.LineTo(Rect.Right, Rect.Bottom - 1);
end;
end;
end;
rtRow: begin
if not (cnTop in CellNeighbours) then
begin
Grid.Canvas.MoveTo(Rect.Left, Rect.Top);
Grid.Canvas.LineTo(Rect.Right, Rect.Top);
end;
if not (cnBottom in CellNeighbours) then
begin
Grid.Canvas.MoveTo(Rect.Left, Rect.Bottom - 1);
Grid.Canvas.LineTo(Rect.Right, Rect.Bottom - 1);
end;
if ((DefinedRanges[i].Direction = rdDown) and (DefinedRanges[i].Col1 > 0) and
(DefinedRanges[i].Row1 > 0) and (DefinedRanges[i].Col1 = ACol) and
(DefinedRanges[i].Row1 = ARow)) or
((DefinedRanges[i].Direction = rdUp) and (DefinedRanges[i].Col2 > 0) and
(DefinedRanges[i].Row2 > 0) and (DefinedRanges[i].Col2 = ACol) and
(DefinedRanges[i].Row2 = ARow)) then
begin
if not (cnLeft in CellNeighbours) then
begin
Grid.Canvas.MoveTo(Rect.Left, Rect.Top);
Grid.Canvas.LineTo(Rect.Left, Rect.Bottom);
end;
end
else if ((DefinedRanges[i].Direction = rdDown) and (DefinedRanges[i].Col2 > 0) and
(DefinedRanges[i].Row2 > 0) and (DefinedRanges[i].Col2 = ACol) and
(DefinedRanges[i].Row2 = ARow)) or
((DefinedRanges[i].Direction = rdUp) and (DefinedRanges[i].Col1 > 0) and
(DefinedRanges[i].Row1 > 0) and (DefinedRanges[i].Col1 = ACol) and
(DefinedRanges[i].Row1 = ARow)) then
begin
if not (cnRight in CellNeighbours) then
begin
Grid.Canvas.MoveTo(Rect.Right - 1, Rect.Top);
Grid.Canvas.LineTo(Rect.Right - 1, Rect.Bottom);
end;
end;
end;
rtCell: begin
if not (cnTop in CellNeighbours) then
begin
Grid.Canvas.MoveTo(Rect.Left, Rect.Top);
Grid.Canvas.LineTo(Rect.Right, Rect.Top);
end;
if not (cnBottom in CellNeighbours) then
begin
Grid.Canvas.MoveTo(Rect.Left, Rect.Bottom - 1);
Grid.Canvas.LineTo(Rect.Right, Rect.Bottom - 1);
end;
if not (cnLeft in CellNeighbours) then
begin
Grid.Canvas.MoveTo(Rect.Left, Rect.Top);
Grid.Canvas.LineTo(Rect.Left, Rect.Bottom);
end;
if not (cnRight in CellNeighbours) then
begin
Grid.Canvas.MoveTo(Rect.Right - 1, Rect.Top);
Grid.Canvas.LineTo(Rect.Right - 1, Rect.Bottom);
end;
end;
end;
end;
end;
end;
if IsEditing and CellInRow(Selection, SheetName, SheetNumber, ACol, ARow) then
begin
Grid.Canvas.Brush.Color := 16776176;
Grid.Canvas.FillRect(Rect);
Grid.{$IFDEF QI_UNICODE}Canvas.TextRectW{$ELSE}Canvas.TextRect{$ENDIF}(Rect, Rect.Left + 2, Rect.Top + 2, Grid.Cells[ACol, ARow]);
CellNeighbours := GetCellNeighbours(Selection, SheetName, SheetNumber,
ACol, ARow);
Grid.Canvas.Pen.Color := clBlue;
Grid.Canvas.Pen.Width := 3;
if not (cnLeft in CellNeighbours) then
begin
Grid.Canvas.MoveTo(Rect.Left, Rect.Top);
Grid.Canvas.LineTo(Rect.Left, Rect.Bottom);
end;
if not (cnRight in CellNeighbours) then
begin
Grid.Canvas.MoveTo(Rect.Right - 1, Rect.Top);
Grid.Canvas.LineTo(Rect.Right - 1, Rect.Bottom);
end;
if not (cnTop in CellNeighbours) then
begin
Grid.Canvas.MoveTo(Rect.Left , Rect.Top);
Grid.Canvas.LineTo(Rect.Right, Rect.Top);
end;
if not (cnBottom in CellNeighbours) then
begin
Grid.Canvas.MoveTo(Rect.Left, Rect.Bottom - 1);
Grid.Canvas.LineTo(Rect.Right, Rect.Bottom - 1);
end;
end;
Grid.DefaultDrawing := true;
end;
procedure GridMoveCurrCell(Grid: {$IFDEF QI_UNICODE}TEmsWideStringGrid{$ELSE}TStringGrid{$ENDIF};
ACol, ARow: integer);
var
OnSelectCell: TSelectCellEvent;
begin
OnSelectCell := Grid.OnSelectCell;
Grid.OnSelectCell := nil;
try
Grid.Col := ACol;
Grid.Row := ARow;
finally
Grid.OnSelectCell := OnSelectCell;
end;
end;
procedure GridSelCell(Grid: {$IFDEF QI_UNICODE}TEmsWideStringGrid{$ELSE}TStringGrid{$ENDIF};
RowNo, ColNo: integer; NeedClear: boolean; var CurrSel: string);
begin
if NeedClear then CurrSel := EmptyStr;
CurrSel := CurrSel + Col2Letter(ColNo) + Row2Number(RowNo) + ';';
GridMoveCurrCell(Grid, ColNo, RowNo);
end;
procedure GridSelRow(Grid: {$IFDEF QI_UNICODE}TEmsWideStringGrid{$ELSE}TStringGrid{$ENDIF};
FirstCol, LastCol, RowNo, StartCol, SkipRows, SkipCols: integer;
NeedClear: boolean; var CurrSel: string);
begin
if NeedClear then CurrSel := EmptyStr;
CurrSel := CurrSel + Col2Letter(FirstCol) + Row2Number(RowNo) + '-' +
Col2Letter(LastCol) + Row2Number(RowNo);
GridMoveCurrCell(Grid, FirstCol + SkipCols, RowNo);
end;
procedure GridSelCol(Grid: {$IFDEF QI_UNICODE}TEmsWideStringGrid{$ELSE}TStringGrid{$ENDIF};
FirstRow, LastRow, ColNo, StartRow, SkipRows, SkipCols: integer;
NeedClear: boolean; var CurrSel: string);
begin
if NeedClear then CurrSel := EmptyStr;
CurrSel := CurrSel + Col2Letter(ColNo) + Row2Number(FirstRow) + '-' +
Col2Letter(ColNo) + Row2Number(LastRow);
GridMoveCurrCell(Grid, ColNo, FirstRow + SkipRows);
end;
procedure GridMouseDown(Grid: {$IFDEF QI_UNICODE}TEmsWideStringGrid{$ELSE}TStringGrid{$ENDIF};
Button: TMouseButton; Shift: TShiftState; X, Y: Integer; FirstCol, LastCol, FirstRow, LastRow,
SkipRows, SkipCols: integer; var CurrSel: string);
var
ARow, ACol, i: integer;
OnDrawCell: TDrawCellEvent;
begin
Grid.MouseToCell(X, Y, ACol, ARow);
// simple select col or row
if Shift = [ssLeft] then
begin
if (ACol = 0) and (ARow > 0) then
GridSelRow(Grid, FirstCol, LastCol, ARow, 0,
SkipRows, SkipCols, true, CurrSel)
else if (ARow = 0) and (ACol > 0) then
GridSelCol(Grid, FirstRow, LastRow, ACol, 0,
SkipRows, SkipCols, true, CurrSel);
end;
// ctrl select col or row
if Shift = [ssLeft, ssCtrl] then
begin
if (ACol = 0) and (ARow > 0) then
GridSelRow(Grid, FirstCol, LastCol, ARow, 0,
SkipRows, SkipCols, false, CurrSel)
else if (ARow = 0) and (ACol > 0) then
GridSelCol(Grid, FirstRow, LastRow, ACol, 0,
SkipRows, SkipCols, false, CurrSel);
end;
// shift select col or row
if Shift = [ssLeft, ssShift] then
begin
OnDrawCell := Grid.OnDrawCell;
Grid.OnDrawCell := nil;
try
if (ACol = 0) {(ACol = StartCol)} and (ARow > 0) then
if Grid.Row <= ARow then
for i := Grid.Row to ARow do
GridSelRow(Grid, FirstCol, LastCol, i, 0, SkipRows, SkipCols,
false, CurrSel)
else for i := Grid.Row downto ARow do
GridSelRow(Grid, FirstCol, LastCol, i, 0, SkipRows, SkipCols,
false, CurrSel)
else if (ARow = 0){(ARow = StartRow)} and (ACol > 0) then
if Grid.Col <= ACol then
for i := Grid.Col to ACol do
GridSelCol(grid, FirstRow, LastRow, i, 0, SkipRows, SkipCols,
false, CurrSel)
else for i := Grid.Col downto ACol do
GridSelCol(Grid, FirstRow, LastRow, i, 0, SkipRows, SkipCols,
false, CurrSel)
finally
Grid.OnDrawCell := OnDrawCell;
Grid.Repaint;
end;
end;
Grid.Repaint;
end;
procedure GridSelectCell(Grid: {$IFDEF QI_UNICODE}TEmsWideStringGrid{$ELSE}TStringGrid{$ENDIF};
ACol, ARow: integer; Shift: TShiftState; var CurrSel: string);
var
i: integer;
begin
if Shift = [] then CurrSel := EmptyStr;
// select simple cell
if Shift = [ssCtrl] then
begin
{ i := FCells.IndexOf(ACol, ARow);
while i > -1 do
begin
FCells.Delete(i);
editCells.Text := FCells.OptimalString;
if FCells.Count > 0 then FCells.Sort(0, FCells.Count - 1, CompareByColRow);
xlsGrid.Repaint;
i := FCells.IndexOf(ACol, ARow);
if i = -1 then Exit;
end;}
GridSelCell(Grid, ARow, ACol, false, CurrSel);
end;
// select range of cells
if Shift = [ssShift] then
begin
if (Grid.Col = ACol) and (Grid.Row <> ARow) then
if Grid.Row < ARow then
for i := Grid.Row to ARow do GridSelCell(Grid, i, ACol, false, CurrSel)
else for i := Grid.Row downto ARow do
GridSelCell(Grid, i, ACol, false, CurrSel);
if (Grid.Row = ARow) and (Grid.Col <> ACol) then
if Grid.Col < ACol then
for i := Grid.Col to ACol do GridSelCell(Grid, ARow, i, false, CurrSel)
else for i := Grid.Col downto ACol do
GridSelCell(Grid, ARow, i, false, CurrSel);
end;
end;
procedure GridFillFixedCells(Grid: {$IFDEF QI_UNICODE}TEmsWideStringGrid{$ELSE}TStringGrid{$ENDIF});
var
i: integer;
begin
Grid.ColWidths[0] := 25;
for i := 0 to Grid.ColCount - 2 do Grid.Cells[i + 1, 0] := Col2Letter(i + 1);
for i := 1 to Grid.RowCount - 1 do Grid.Cells[0, i] := Row2Number(i);
end;
{procedure GridClearDataCell(Grid: TStringGrid);
var
i, j: integer;
begin
for i := 1 to Grid.ColCount - 1 do
for j := 1 to Grid.RowCount - 1 do
Grid.Cells[i, j] := EmptyStr;
end;}
{$ENDIF}
{$IFDEF QI_UNICODE}
procedure CSVStringToStrings(
const Str: WideString; Quote, Separator: Char; AStrings: TWideStrings);
{$ELSE}
procedure CSVStringToStrings(
const Str: string; Quote, Separator: Char; AStrings: TStrings);
{$ENDIF}
var
i: Integer;
is_quote, in_quote, is_first, is_separator, quote_in_quote, wait_separator: Boolean;
sss: {$IFDEF QI_UNICODE}WideString{$ELSE}string{$ENDIF};
begin
if Separator = #0 then Exit;
AStrings.Clear;
is_first := true;
in_quote := false;
quote_in_quote := false;
wait_separator := false;
for i := 1 to Length(Str) do
begin
if is_first then
begin
sss := '';
in_quote := (Quote <> #0) and (Str[i] = {$IFDEF QI_UNICODE}WideChar{$ELSE}Char{$ENDIF}(Quote));
is_first := false;
if in_quote then Continue;
end;
is_separator := Str[i] = {$IFDEF QI_UNICODE}WideChar{$ELSE}Char{$ENDIF}(Separator);
if is_separator and not in_quote then
begin
AStrings.Add(sss);
is_first := true;
sss := '';
Continue;
end;
if wait_separator then
if is_separator then
begin
wait_separator := false;
is_first := true;
AStrings.Add(sss);
Continue;
end
else begin
Continue;
end;
is_quote := (Quote <> #0) and (Str[i] = {$IFDEF QI_UNICODE}WideChar{$ELSE}Char{$ENDIF}(Quote));
if quote_in_quote then
begin
if is_quote then
begin
sss := sss + Quote;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -