以下是该函数,
程序在执行数次操作后出现invalid pointer异常,谁有经验帮忙解决一下??
function TfrmXzxc.MoveSelCarsToDestPos(CellsSource,CellsDest :CCellRange;var strErrorMsg:String):Boolean ;
var
nRow,i,j,k,DestRow : Integer;
//计算需要拖放的车辆总数
nDragCellCount : Integer; //定义拖放车辆总数
nAdjustDestRowCount :Integer; //定义由于本股道进行拖放需要调整目标选择区行数
nAdjustSourceRowCount :Integer; //定义由于本股道进行拖放需要调整源选择区行数
nLocomotive :integer ; //计算目标股道尾是否有机车
nCol : Integer;
nMin,nMax : Integer;
bSelect : Boolean;
nStationSourcePos,nStationDestpos : Integer;
nSourceGDM : string;
UndoMsg :UNDO_MSG;
begin
Result := False;
nCol := CellsDest.nMinCol ; ////删除目标区上部
if(CellsDest.nMinRow <CAR_POS_START_ROW) then
CellsDest.nMinRow := CAR_POS_START_ROW; //删除选择区上部机车位
if(CellsSource.nMinRow < CAR_POS_START_ROW) then
CellsSource.nMinRow := CAR_POS_START_ROW;
if(cellsSource.nMaxCol <> CellsSource.nMinCol) then
begin
strErrorMsg :='对不起,只能拖放同一个股道(列)的车辆!';
Exit;
end; nDragCellCount := 0; //定义拖放车辆总数
nAdjustDestRowCount := 0; //定义由于本股道进行拖放需要调整目标选择区行数
nAdjustSourceRowCount := 0; //定义由于本股道进行拖放需要调整源选择区行数 //删除选择区中下部的空单元格及机车位
nMin := -1;
nMax := -1;
bSelect := False;
for nRow := CellsSource.nMinRow to CellsSource.nMaxRow do
begin
if StrToIntDef(Cell1.GetCellNote(CellsSource.nMinCol ,nRow,0),-1) > -1 then
begin
nDragCellCount := nDragCellCount + 1;
if not bSelect then
begin
nMin := nRow;
bSelect := True;
end;
nMax := nRow;
end;
end;
CellsSource.nMinRow := nMin;
cellsSource.nMaxRow := nMax;//保存有效车辆区域 //检查是目标位置否在选择区内部
if(CellsSource.nMinCol=CellsDest.nMinCol) and (CellsDest.nMinRow>=CellsSource.nMinRow) and (CellsDest.nMinRow<=CellsSource.nMaxRow) then
begin
strErrorMsg :='对不起,目标位置不能在选择区内部!';
Exit;
end; if(nDragCellCount<=0) then //选中的空车辆,直接返回
begin
strErrorMsg := '对不起,请先选择需要拖放的车辆!';
Exit;
end; if((gd_desc[CellsDest.nMinCol-1].nClzs+nDragCellCount) > gd_desc[CellsDest.nMinCol-1].nRcs)
and (CellsDest.nMinCol <> CellsSource.nMinCol) then
begin
strErrorMsg := '对不起,目标股道已放不下拖放的车辆了!';
Exit;
end; //移动数组,同一股道调车情况处理办法
if CellsSource.nMinCol = CellsDest.nMinCol then
begin//下到上
if (CellsSource.nMinRow > CellsDest.nMinRow) then
begin
CellsSource.nMinRow := CellsSource.nMinRow + nDragCellCount;
CellsSource.nMaxRow := CellsSource.nMaxRow + nDragCellCount;
CellsDest.nMinRow := CAR_POS_START_ROW;
CellsDest.nMaxRow := CAR_POS_START_ROW + nDragCellCount - 1;
end else
begin//上到下
CellsDest.nMinRow := CAR_POS_START_ROW + Length(gd_desc[nCol - 1].v_sy);
CellsDest.nMaxRow := CellsDest.nMinRow + nDragCellCount - 1 ;
end;
end;
SetLength(gd_desc[nCol-1].v_sy,gd_desc[nCol-1].nClzs + nDragCellCount);
//确定目标位置,空出相应位置
//目标为空白单元格,需要找到其上的第一个空白单元格
if not (StrToIntDef(Cell1.GetCellNote(CellsDest.nMinCol ,CellsDest.nMinRow,0),-1) > -1) then
begin
CellsDest.nMinRow := gd_desc[nCol - 1].nClzs + CAR_POS_START_ROW ;
CellsDest.nMaxRow := CellsDest.nMinRow + nDragCellCount -1; if(CellsDest.nMinCol = CellsSource.nMinCol) then//如果是在同一股道进行甩挂操作
begin
nAdjustDestRowCount := nDragCellCount;
end;
end else //目标为有内容的单元格,需要向下移位量为:nDragCellCount
begin
//空出目标区车辆位置 for i:= High(gd_desc[nCol - 1].v_sy) - nDragCellCount downto CellsDest.nMinRow - CAR_POS_START_ROW do
begin
if (i < gd_desc[nCol-1].nClzs) then
begin
gd_desc[nCol - 1].v_sy[i+nDragCellCount] := gd_desc[nCol - 1].v_sy[i];
SwapTwoCells(i+CAR_POS_START_ROW,nCol,i+CAR_POS_START_ROW+nDragCellCount,nCol);
end else
Break;
end;
end; j := CellsSource.nMinRow - CAR_POS_START_ROW ;
// SetLength(gd_desc[nCol-1].v_sy,gd_desc[nCol-1].nClzs + nDragCellCount);
for i:= CellsDest.nMinRow - CAR_POS_START_ROW to CellsDest.nMaxRow - CAR_POS_START_ROW do
begin
gd_desc[nCol - 1].v_sy[i] := gd_desc[CellsSource.nMinCol - 1].v_sy[j];
j := j + 1;
end;
gd_desc[nCol - 1].nClzs := gd_desc[nCol - 1].nClzs + nDragCellCount;
// SetLength(gd_desc[nCol-1].v_sy,gd_desc[nCol - 1].nClzs); //开始进行甩挂 destRow := CellsDest.nMinRow ;
for nRow := CellsSource.nMinRow to CellsSource.nMaxRow do
begin
SwapTwoCells(nRow,CellsSource.nMinCol,destRow,CellsDest.nMinCol);
destRow := destRow + 1;
end; //移动数据源
j := 0;
DestRow := CellsSource.nMinRow - CAR_POS_START_ROW ;
nCol := CellsSource.nMinCol;
for i := CellsSource.nMaxRow - CAR_POS_START_ROW + 1 to High(gd_desc[nCol - 1].v_sy) do
begin
gd_desc[nCol - 1].v_sy[DestRow] := gd_desc[nCol - 1].v_sy[i] ;
SwapTwoCells(i+CAR_POS_START_ROW,nCol,DestRow+CAR_POS_START_ROW,nCol);
DestRow := DestRow + 1;
end;
gd_desc[nCol - 1].nClzs := gd_desc[nCol - 1].nClzs - nDragCellCount;
SetLength(gd_desc[nCol-1].v_sy,gd_desc[nCol - 1].nClzs); if (CellsSource.nMinCol = CellsDest.nMinCol)and (CellsSource.nMinRow < CellsDest.nMinRow) then
begin//,同股道甩挂后重新指定选择区域,上到下,重新指定选择目标区域
CellsDest.nMinRow := CellsDest.nMinRow - nDragCellCount;
CellsDest.nMaxRow := CellsDest.nMaxRow - nDragCellCount;
end;
{
//移动整列车
if (gd_desc[CellsSource.nMinCol - 1].nClzs = nDragCellCount) then
begin
if Trim(Cell1.GetCellString(CellsDest.nMinCol,1,0)) = '' then
begin
//设置第一行车次标志
SwapTwoCells(1,CellsSource.nMinCol,1,CellsDest.nMinCol);
for i := Low(station_train) to High(station_train) do
begin
if Trim(station_train[i].GDM) = Trim(gd_desc[CellsSource.nMinCol - 1].strGdm) then
begin
nStationSourcePos := i;
Break;
end;
end;
station_train[nStationSourcePos].GDM := DestGdm ;
//刷新机车位
RefreshAllLocomotiveCells(Cell1);
end;
end; } Cell1.SelectRange(CellsDest.nMinCol,CellsDest.nMinRow,CellsDest.nMinCol,CellsDest.nMaxRow);
FCellcol := CellsDest.nMinCol;//确保在不重新选择单元格时,取目标格的值
result := True;
程序在执行数次操作后出现invalid pointer异常,谁有经验帮忙解决一下??
function TfrmXzxc.MoveSelCarsToDestPos(CellsSource,CellsDest :CCellRange;var strErrorMsg:String):Boolean ;
var
nRow,i,j,k,DestRow : Integer;
//计算需要拖放的车辆总数
nDragCellCount : Integer; //定义拖放车辆总数
nAdjustDestRowCount :Integer; //定义由于本股道进行拖放需要调整目标选择区行数
nAdjustSourceRowCount :Integer; //定义由于本股道进行拖放需要调整源选择区行数
nLocomotive :integer ; //计算目标股道尾是否有机车
nCol : Integer;
nMin,nMax : Integer;
bSelect : Boolean;
nStationSourcePos,nStationDestpos : Integer;
nSourceGDM : string;
UndoMsg :UNDO_MSG;
begin
Result := False;
nCol := CellsDest.nMinCol ; ////删除目标区上部
if(CellsDest.nMinRow <CAR_POS_START_ROW) then
CellsDest.nMinRow := CAR_POS_START_ROW; //删除选择区上部机车位
if(CellsSource.nMinRow < CAR_POS_START_ROW) then
CellsSource.nMinRow := CAR_POS_START_ROW;
if(cellsSource.nMaxCol <> CellsSource.nMinCol) then
begin
strErrorMsg :='对不起,只能拖放同一个股道(列)的车辆!';
Exit;
end; nDragCellCount := 0; //定义拖放车辆总数
nAdjustDestRowCount := 0; //定义由于本股道进行拖放需要调整目标选择区行数
nAdjustSourceRowCount := 0; //定义由于本股道进行拖放需要调整源选择区行数 //删除选择区中下部的空单元格及机车位
nMin := -1;
nMax := -1;
bSelect := False;
for nRow := CellsSource.nMinRow to CellsSource.nMaxRow do
begin
if StrToIntDef(Cell1.GetCellNote(CellsSource.nMinCol ,nRow,0),-1) > -1 then
begin
nDragCellCount := nDragCellCount + 1;
if not bSelect then
begin
nMin := nRow;
bSelect := True;
end;
nMax := nRow;
end;
end;
CellsSource.nMinRow := nMin;
cellsSource.nMaxRow := nMax;//保存有效车辆区域 //检查是目标位置否在选择区内部
if(CellsSource.nMinCol=CellsDest.nMinCol) and (CellsDest.nMinRow>=CellsSource.nMinRow) and (CellsDest.nMinRow<=CellsSource.nMaxRow) then
begin
strErrorMsg :='对不起,目标位置不能在选择区内部!';
Exit;
end; if(nDragCellCount<=0) then //选中的空车辆,直接返回
begin
strErrorMsg := '对不起,请先选择需要拖放的车辆!';
Exit;
end; if((gd_desc[CellsDest.nMinCol-1].nClzs+nDragCellCount) > gd_desc[CellsDest.nMinCol-1].nRcs)
and (CellsDest.nMinCol <> CellsSource.nMinCol) then
begin
strErrorMsg := '对不起,目标股道已放不下拖放的车辆了!';
Exit;
end; //移动数组,同一股道调车情况处理办法
if CellsSource.nMinCol = CellsDest.nMinCol then
begin//下到上
if (CellsSource.nMinRow > CellsDest.nMinRow) then
begin
CellsSource.nMinRow := CellsSource.nMinRow + nDragCellCount;
CellsSource.nMaxRow := CellsSource.nMaxRow + nDragCellCount;
CellsDest.nMinRow := CAR_POS_START_ROW;
CellsDest.nMaxRow := CAR_POS_START_ROW + nDragCellCount - 1;
end else
begin//上到下
CellsDest.nMinRow := CAR_POS_START_ROW + Length(gd_desc[nCol - 1].v_sy);
CellsDest.nMaxRow := CellsDest.nMinRow + nDragCellCount - 1 ;
end;
end;
SetLength(gd_desc[nCol-1].v_sy,gd_desc[nCol-1].nClzs + nDragCellCount);
//确定目标位置,空出相应位置
//目标为空白单元格,需要找到其上的第一个空白单元格
if not (StrToIntDef(Cell1.GetCellNote(CellsDest.nMinCol ,CellsDest.nMinRow,0),-1) > -1) then
begin
CellsDest.nMinRow := gd_desc[nCol - 1].nClzs + CAR_POS_START_ROW ;
CellsDest.nMaxRow := CellsDest.nMinRow + nDragCellCount -1; if(CellsDest.nMinCol = CellsSource.nMinCol) then//如果是在同一股道进行甩挂操作
begin
nAdjustDestRowCount := nDragCellCount;
end;
end else //目标为有内容的单元格,需要向下移位量为:nDragCellCount
begin
//空出目标区车辆位置 for i:= High(gd_desc[nCol - 1].v_sy) - nDragCellCount downto CellsDest.nMinRow - CAR_POS_START_ROW do
begin
if (i < gd_desc[nCol-1].nClzs) then
begin
gd_desc[nCol - 1].v_sy[i+nDragCellCount] := gd_desc[nCol - 1].v_sy[i];
SwapTwoCells(i+CAR_POS_START_ROW,nCol,i+CAR_POS_START_ROW+nDragCellCount,nCol);
end else
Break;
end;
end; j := CellsSource.nMinRow - CAR_POS_START_ROW ;
// SetLength(gd_desc[nCol-1].v_sy,gd_desc[nCol-1].nClzs + nDragCellCount);
for i:= CellsDest.nMinRow - CAR_POS_START_ROW to CellsDest.nMaxRow - CAR_POS_START_ROW do
begin
gd_desc[nCol - 1].v_sy[i] := gd_desc[CellsSource.nMinCol - 1].v_sy[j];
j := j + 1;
end;
gd_desc[nCol - 1].nClzs := gd_desc[nCol - 1].nClzs + nDragCellCount;
// SetLength(gd_desc[nCol-1].v_sy,gd_desc[nCol - 1].nClzs); //开始进行甩挂 destRow := CellsDest.nMinRow ;
for nRow := CellsSource.nMinRow to CellsSource.nMaxRow do
begin
SwapTwoCells(nRow,CellsSource.nMinCol,destRow,CellsDest.nMinCol);
destRow := destRow + 1;
end; //移动数据源
j := 0;
DestRow := CellsSource.nMinRow - CAR_POS_START_ROW ;
nCol := CellsSource.nMinCol;
for i := CellsSource.nMaxRow - CAR_POS_START_ROW + 1 to High(gd_desc[nCol - 1].v_sy) do
begin
gd_desc[nCol - 1].v_sy[DestRow] := gd_desc[nCol - 1].v_sy[i] ;
SwapTwoCells(i+CAR_POS_START_ROW,nCol,DestRow+CAR_POS_START_ROW,nCol);
DestRow := DestRow + 1;
end;
gd_desc[nCol - 1].nClzs := gd_desc[nCol - 1].nClzs - nDragCellCount;
SetLength(gd_desc[nCol-1].v_sy,gd_desc[nCol - 1].nClzs); if (CellsSource.nMinCol = CellsDest.nMinCol)and (CellsSource.nMinRow < CellsDest.nMinRow) then
begin//,同股道甩挂后重新指定选择区域,上到下,重新指定选择目标区域
CellsDest.nMinRow := CellsDest.nMinRow - nDragCellCount;
CellsDest.nMaxRow := CellsDest.nMaxRow - nDragCellCount;
end;
{
//移动整列车
if (gd_desc[CellsSource.nMinCol - 1].nClzs = nDragCellCount) then
begin
if Trim(Cell1.GetCellString(CellsDest.nMinCol,1,0)) = '' then
begin
//设置第一行车次标志
SwapTwoCells(1,CellsSource.nMinCol,1,CellsDest.nMinCol);
for i := Low(station_train) to High(station_train) do
begin
if Trim(station_train[i].GDM) = Trim(gd_desc[CellsSource.nMinCol - 1].strGdm) then
begin
nStationSourcePos := i;
Break;
end;
end;
station_train[nStationSourcePos].GDM := DestGdm ;
//刷新机车位
RefreshAllLocomotiveCells(Cell1);
end;
end; } Cell1.SelectRange(CellsDest.nMinCol,CellsDest.nMinRow,CellsDest.nMinCol,CellsDest.nMaxRow);
FCellcol := CellsDest.nMinCol;//确保在不重新选择单元格时,取目标格的值
result := True;
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货