廣告

2025 年 1 月
 12345
6789101112
13141516171819
20212223242526
2728293031  

彙整

由168.95.1.1(hinet) NSLOOKUP 查詢DNS系統自動補上尾碼問題

由168.95.1.1(hinet) NSLOOKUP 查詢DNS系統自動補上尾碼問題

今天為了要查尋由外面連入對外的DNS設定值是否正確,就查了nslookup,發現系統自動會加上對外網域已經停用的尾碼:

原先申請的網域 123.com,內部AD也使用123.com架設,因公司合併,新申請456.com,123.com到期後中斷,但是內部AD不變動,維持123.com

==================

nslookup

server 168.95.1.1

查詢www.google.com

得到的是 www.google.com.123.com IP已是別的固定IP

一開始還以為是中毒還是DNS被轉向,但是基本上都排除這些問題了………………

本機的TCP\IP內的DNS沒有尾碼設定,可是發現退租的winpex-gl.com已經有其它IP位置,不知道是不是網路蟑螂,在一些網域退租當下租走,造成有些公司若要再租回,就得花錢解決? 純屬猜測……

目前我是使用GPO設定所有機器加上尾碼搜尋清單 456.com,就可避免這個問題出現。

1

 2

3

Delphi 2010自帶TIdFTP的中文問題

DELPHI7 + INDY

抓檔前先轉UTF8Encode
filename:= UTF8Encode(filename);  
FIdFtp.Get(filename,tStream,true);

未測試………………

==================================================================================

出處:http://hi.baidu.com/syncgrey/blog/item/8c894e823c7f78aa6c8119f1.html

1、Delphi 2010自帶TIdFTP的中文問題
  最近使用TIdTFP,使用ChangeDir切換到中文目錄時報錯,錯誤提示中的中文目錄成了一串“?”號,閱讀源代碼得知,該控件的默認IOHandle的默認Encoding是ASCII(代碼頁為20127),ITdFTP在Connect方法中,連接成功後,有這麼一句:

    // RLebeau: must not send/receive UTF-8 before negotiating for it…
    IOHandler.DefStringEncoding := Indy8BitEncoding;

再轉到Indy8BitEncoding 中看看:

function Indy8BitEncoding(const AOwnedByIndy: Boolean = True): TIdTextEncoding;
var
  LEncoding: TIdTextEncoding;
begin
  if not AOwnedByIndy then begin
    LEncoding := TIdTextEncoding.GetEncoding(28591);
  end else
  begin
    if GId8BitEncoding = nil then begin
      LEncoding := TIdTextEncoding.GetEncoding( 28591);
      if InterlockedCompareExchangePtr(Pointer(GId8BitEncoding), LEncoding, nil) <> nil then begin
        LEncoding.Free;
      end;
    end;
    LEncoding := GId8BitEncoding;
  end;
  Result := LEncoding;
end;

可以看到,這裡會創建(如果還沒創建的話)返回一個代碼頁為28591 的TEncoding,那這個28591 到底是啥子呢?搜索結果如下:

  28591 iso-8859-1 Western European (ISO)

原來是西歐的編碼,不支持中文就不足為奇了,那該如何處理呢?只要在調用TIdFTP.Connect 後,增加一句

TIdFTP.IOHandler.DefStringEncoding := TEncoding.Default

就正常了,注意一定要放在Connect 之後,否則會被Connect 方法重置為28591 代碼頁。

VMware vCenter Converter Standalone Client轉換時出現Multiple connections to as server or shared resource y the same user, using more than one user name, are not allowed

VMware vCenter Converter Standalone Client 轉換時出現 Multiple connections to as server or shared resource y the same user, using more than one user name, are not allowed

1

原本用IP連,會一直出現這個問題,但是改用電腦名稱連就OK了,之後再用IP連也都正常,真是怪 /_\

[DELPHI] cxGrid的使用方法

朋友貼給我的,只知道是大陸網站上分享的資料,可在cxGrid內使用CheckBox喔!!!只是用了之後以前可使用 Shift 選區段的功能似乎不能用了。

======================================================================

cxGrid的使用方法

cxGrid功能強大,適合做企業級的複雜查詢。非常方便。

但是對其用法介紹的並不多,在此總結他人的使用經驗和自己的一點小經驗,供大家參考。

(1)動態設置顯示格式

procedure SetDisplayFormat(ACtrlData: TClientDataSet;

  TbView: TcxGridDBTableView);

var

  i: integer;

begin

  if ACtrlData.RecordCount <= 0 then Exit;

  try

    TbView.ClearItems;

    ACtrlData.First;

    for i := 0 to ACtrlData.RecordCount – 1 do

    begin

      if ACtrlData.FieldByName(‘SQBF_DisplayInGrid’).AsString = ‘1’ then //在表格中顯示

      with TbView.CreateColumn do

      begin

        DataBinding.FieldName := ACtrlData.FieldByName(‘SQBF_FieldName’).AsString;

        Caption := ACtrlData.FieldByName(‘SQBF_Caption’).AsString; //欄位中文標題

        Hint := ACtrlData.FieldByName(‘SQBF_Hint’).AsString;

        Width := ACtrlData.FieldByName(‘SQBF_Width’).AsInteger;

        HeaderAlignmentHorz := taCenter;

      end;

      ACtrlData.Next;

    end;

  except

    on E: Exception do

      SaveLog(‘設置顯示格式時出錯:’ + E.Message);

  end;

end;

(2)顯示行號

procedure TFmQueryBase.cxDBViewMasterCustomDrawIndicatorCell(

  Sender: TcxGridTableView; ACanvas: TcxCanvas;

  AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean);

var

  FValue: string;

  FBounds: TRect;

begin

  FBounds := AViewInfo.Bounds;

  if (AViewInfo is TcxGridIndicatorRowItemViewInfo) then

  begin

    ACanvas.FillRect(FBounds);

    ACanvas.DrawComplexFrame(FBounds, clBlack, clBlack, [bBottom, bLeft, bRight], 1);

    FValue := IntToStr(TcxGridIndicatorRowItemViewInfo(AViewInfo).GridRecord.Index+1);

    InflateRect(FBounds, -3, -2); //Platform specific. May not work on Linux.

    ACanvas.Font.Color := clBlack;

    ACanvas.Brush.Style := bsClear;

    ACanvas.DrawText(FValue, FBounds, cxAlignCenter or cxAlignTop);

    ADone := True;

  end;

end;

(3)設置顯示格式,我的專案要求先動態添加欄位,這時不知道欄位類型,所以設置DisplayFormat不方便,我還沒有找到好方法。

所以採用打開資料集後再設置:

procedure TFmQueryBase.cdsMasterAfterOpen(DataSet: TDataSet);

var

  i: Integer;

begin

  for i := 0 to cxDBViewMaster.DataController.DataSet.FieldCount -1 do

  begin

    if cxDBViewMaster.DataController.DataSet.Fields[i] is TNumericField then

    begin

      if Pos(‘AMOUNT’, UpperCase(cxDBViewMaster.DataController.DataSet.Fields[i].FieldName)) > 0 then

      begin

        TNumericField(cxDBViewMaster.DataController.DataSet.Fields[i]).DisplayFormat := ‘#,##0.000’;

        Continue;

      end;

      if Pos(‘QUANTITY’, UpperCase(cxDBViewMaster.DataController.DataSet.Fields[i].FieldName)) > 0 then

      begin

        TNumericField(cxDBViewMaster.DataController.DataSet.Fields[i]).DisplayFormat := ‘#,##0.000’;

        Continue;

      end;

       if Pos(‘MONEY’, UpperCase(cxDBViewMaster.DataController.DataSet.Fields[i].FieldName)) > 0 then

      begin

        TNumericField(cxDBViewMaster.DataController.DataSet.Fields[i]).DisplayFormat := ‘#,##0.00’;

        Continue;

      end;

   end;

  end;

end;

最近在學習使用cxGrid,安裝的版本是ExpressQuantumGrid   Suite   v5.10 

我發現這個控制項功能雖然強大,但是非常難用。

現在我手頭就有幾個問題還沒解決:

  1)主從模式下導出Excel中文會產生亂碼,而且從表內容沒有導出。

我不知道是不是因為我的欄位名包括單引號的原因。

導出代碼:ExportGrid4ToExcel(FileName,   cxGrid); 

  2)主從模式下通過按鈕對從表添加/刪除行,代碼怎么寫。

附:單表添加/刪除行的代碼

  procedure   TFormAccount.cxButtonNewClick(Sender:   TObject); 

  begin 

      Self.tvAccount.DataController.Append; 

      Self.tvAccount.Columns[0].Focused   :=   True; 

      cxGrid.SetFocus; 

  end; 

  procedure   TFormAccount.cxButtonDeleteClick(Sender:   TObject); 

  begin 

      if   Self.tvAccount.DataController.RowCount   =   0   then 

          Exit; 

      if   Application.MessageBox(‘確認刪除當前記錄?’,   ‘確認刪除’, 

          MB_YesNo   +   MB_IconQuestion)   =   IDNO   then 

          Exit; 

      Self.tvAccount.DataController.DeleteFocused; 

  end; 

  3)動態創建主從結構出錯(Compiler沒錯,運行時出現系統錯誤0000000018),

我使用了二個ADOStoreProcedure作主從表

代碼如下:

  var 

      Level:   TcxGridLevel; 

      GridView:   TcxGridDBTableView; 

  begin 

      Level   :=   cxGrid1.Levels[0].Add; 

      GridView   :=   TcxGridDBTableView(cxGrid1.CreateView(TcxGridDBTableView)); 

      GridView.DataController.DataSource   :=   Self.dsDetail; 

      GridView.DataController.KeyFieldNames   :=   ‘PurchOrderID;POLineNbr;PromiseDate;ReceiverDate’; 

      GridView.DataController.MasterKeyFieldNames   :=   ‘VendorID’; 

      GridView.DataController.DetailKeyFieldNames   :=   ‘VendorID’; 

      GridView.DataController.DataModeController.SmartRefresh   :=   True; 

      GridView.OptionsCustomize.ColumnHiding   :=   True; 

      GridView.OptionsCustomize.ColumnsQuickCustomization   :=   True; 

      GridView.OptionsData.Deleting   :=   False; 

      GridView.OptionsData.Inserting   :=   False; 

      GridView.OptionsView.Indicator   :=   True; 

      Level.GridView   :=   GridView; 

      GridView   :=   TcxGridDBTableView(cxGrid1.Levels[0].GridView); 

      GridView.DataController.KeyFieldNames   :=   ‘VendorID’; 

      GridView.OptionsView.GroupByBox   :=   False; 

      //顯示主表內容

      tvResult.BeginUpdate; 

      tvResult.ClearItems; 

      tvResult.DataController.CreateAllItems; 

      tvResult.EndUpdate; 

      //顯示明細表內容

      GridView   :=   TcxGridDBTableView(cxGrid1.Levels[0].Items[0].GridView); 

      GridView.BeginUpdate; 

      GridView.ClearItems; 

      GridView.DataController.CreateAllItems; 

      GridView.DataController.Refresh; 

      GridView.EndUpdate; 

  end; 

此樓回復Re:


小技巧:用代碼展開/收縮主從結構

  Self.tvDepartment.ViewData.Expand(True); 

  Self.tvDepartment.ViewData.Collaspe(True); 

注:tvDepartment為主表對應的TableView

此樓回復Re:


你說的這幾個問題我也遇到過。

第一個問題是編碼的問題,修改了其中關於編碼的函數,OK. 

第二個問題在cxGrid的社區可以找到解答,但從表必須滿足某種條件,例如關鍵字排序。

第三個問題的解決辦法,你可以嘗試在動態創建的代碼前後加上:

  grid.beginupdate; 

  … 

  grid.endupdate 

來解決。

此樓回復Re:


沒用過

不要經常使用三方控制項

此樓回復Re:


to   tttk(網路芝麻):

第一個問題:如何修改啊,貼出代碼

第二個問題:沒搜到啊

第三個問題:試一下再說

此樓回復Re:


不要經常使用三方控制項

  ====================== 

我感覺不用cxGrid的話,沒必要用Delphi了,呵呵

此樓回復Re:


樓上這話是不是有點問題?DELPHI能做得事情很多很多,難道非要用CXGRID?CXGRID不是用DELPHI做出來得?

此樓回復Re:


沒用過…..

此樓回復Re:


回復人:   zxkid(沒有人會像我這樣…)   (   )   信譽:101     2006-01-06   16:58:00     得分:   0     

不要經常使用三方控制項

  ====================== 

我感覺不用cxGrid的話,沒必要用Delphi了,呵呵

  ********** 

樓主乃天人也!!

此樓回復Re:


呵呵

此樓回復Re:


cxGrid比較不錯,我也使用過導出到Excel,沒有遇到你說的亂碼

主從表也沒有問題的,其實跟單表操作還不是一回事

此樓回復Re:


up

此樓回復Re:


沒用過cxGrid,以後考慮

此樓回復Re:


樓主乃天人也!!

  ============================= 

  Delphi下有cxGrid,   .NET下有XtraGrid,   它們都是同一公司出的。

遲早都會轉到.NET,所以。。。

此樓回復Re:


路過

此樓回復Re:


用過,挺好,只會使用最簡單的。

此樓回復Re:


發一個郵件給我,我把解決亂碼後的源代碼發一分給你,放到你的專案檔夾下即可。

  tttk2000@hotmail.com

此樓回復Re:


第二個問題:https://www.devexpress.com/Support/Center/default.aspx?view=ViewIssue&issueid=B2691

此樓回復Re:


謝謝tttk(網路芝麻)   

第二個問題:我現在直接讓用戶用導航條的刪除/添加按鈕了。根據你給的網址上的內容我知道大概該怎么寫了,有空再試試。

第一個問題:不光是亂碼問題,還有從表內容沒導出的問題。

只有一個表的話是不會出現亂碼的。

第三個問題:還沒來得及試。

此樓回復Re:


第一個問題:看了一下幫助,原來cxGrid不支持主從表的導出,只能導出主表(頂層表)的內容。暈

此樓回復Re:


貼一些小技巧,希望與各位使用cxGrid的朋友共同交流

各位有什么好個技巧也可以貼出來: 

技巧二:在內置右鍵功能表的後面增加功能表項

首先應在Form上加一個cxGridPopupMenu控制項 以啟用右鍵功能表

  UseBuildInPopupMenus設為True 

  procedure   TFormItemList.FormCreate(Sender:   TObject); 

  var 

      AMenu:   TComponent; 

      FMenuItem,   FSubMenuItem:   TMenuItem; 

  begin 

      AMenu   :=   nil; 

      if   cxGridPopupMenu.BuiltInPopupMenus.Count   =   0   then 

          Exit; 

      AMenu   :=   cxGridPopupMenu.BuiltInPopupMenus[0].PopupMenu; //第一個內置右鍵功能表(表頭功能表) 

      if   Assigned(AMenu)   and   AMenu.InheritsFrom(TPopupMenu)   then 

      begin 

          TPopupMenu(AMenu).AutoHotkeys   :=   maManual;         //手動熱鍵

          //————————- 

          FMenuItem   :=   TMenuItem.Create(Self); 

          FMenuItem.Caption   :=   ‘-‘; 

          FMenuItem.Name   :=   ‘miLineForGroup’; 

          TPopupMenu(AMenu).Items.Add(FMenuItem); 

          //展開所有組

          FMenuItem   :=   TMenuItem.Create(Self); 

          FMenuItem.Name   :=   ‘miExpandAllGroup’; 

          FMenuItem.Caption   :=   ‘展開所有組(&X)’; 

          FMenuItem.OnClick   :=   miExpandAllGroupClick; 

          TPopupMenu(AMenu).Items.Add(FMenuItem); 

          //收縮所有組

          FMenuItem   :=   TMenuItem.Create(Self); 

          FMenuItem.Name   :=   ‘miCollapseAllGroup’; 

          FMenuItem.Caption   :=   ‘收縮所有組(&O)’; 

          FMenuItem.OnClick   :=   miCollapseAllGroupClick; 

          TPopupMenu(AMenu).Items.Add(FMenuItem); 

          //————————- 

          FMenuItem   :=   TMenuItem.Create(Self); 

          FMenuItem.Caption   :=   ‘-‘; 

          TPopupMenu(AMenu).Items.Add(FMenuItem); 

          //過濾面板

          FMenuItem   :=   TMenuItem.Create(Self); 

          FMenuItem.Name   :=   ‘miFilterPanel’; 

          FMenuItem.Caption   :=   ‘過濾面板(&P)’; 

          //自動顯示

          FSubMenuItem   :=   TMenuItem.Create(Self); 

          FSubMenuItem.Name   :=   ‘miFilterPanelAuto’; 

          FSubMenuItem.Caption   :=   ‘自動(&A)’; 

          FSubMenuItem.RadioItem   :=   True; 

          FSubMenuItem.GroupIndex   :=   5; //指定同一組

          FSubMenuItem.Checked   :=   True; 

          FSubMenuItem.OnClick   :=   miFilterPanelClick; 

          FMenuItem.Add(FSubMenuItem); //加入二級子功能表

          //總是顯示

          FSubMenuItem   :=   TMenuItem.Create(Self); 

          FSubMenuItem.Name   :=   ‘miFilterPanelAlways’; 

          FSubMenuItem.Caption   :=   ‘總是顯示(&W)’; 

          FSubMenuItem.RadioItem   :=   True; 

          FSubMenuItem.GroupIndex   :=   5; 

          FSubMenuItem.OnClick   :=   miFilterPanelClick; 

          FMenuItem.Add(FSubMenuItem); 

          //從不顯示

          FSubMenuItem   :=   TMenuItem.Create(Self); 

          FSubMenuItem.Name   :=   ‘miFilterPanelNerver’; 

          FSubMenuItem.Caption   :=   ‘從不顯示(&N)’; 

          FSubMenuItem.RadioItem   :=   True; 

          FSubMenuItem.GroupIndex   :=   5; 

          FSubMenuItem.OnClick   :=   miFilterPanelClick; 

          FMenuItem.Add(FSubMenuItem); 

          TPopupMenu(AMenu).Items.Add(FMenuItem); 

          //自定義過濾

          FMenuItem   :=   TMenuItem.Create(Self); 

          FMenuItem.Name   :=   ‘miCustomFilter’; 

          FMenuItem.Caption   :=   ‘自定義過濾(&M)’; 

          FMenuItem.OnClick   :=   miCustomFilterClick; 

          TPopupMenu(AMenu).Items.Add(FMenuItem); 

          //過濾管理器

          FMenuItem   :=   TMenuItem.Create(Self); 

          FMenuItem.Name   :=   ‘miFilterBuilder’; 

          TPopupMenu(AMenu).Images.AddImage(FormMain.ImageListExtend,   44); //添加圖示圖像

          FMenuItem.ImageIndex   :=   TPopupMenu(AMenu).Images.Count   -   1; //指定圖示序號

          FMenuItem.Caption   :=   ‘過濾管理器’; 

          FMenuItem.OnClick   :=   Self.miFilterBuilderClick; 

          TPopupMenu(AMenu).Items.Add(FMenuItem); 

          //——————— 

          FMenuItem   :=   TMenuItem.Create(Self); 

          FMenuItem.Caption   :=   ‘-‘; 

          TPopupMenu(AMenu).Items.Add(FMenuItem); 

          //導出

          FMenuItem   :=   TMenuItem.Create(Self); 

          FMenuItem.Name   :=   ‘miExport’; 

          TPopupMenu(AMenu).Images.AddImage(FormMain.ImageListExtend,   37); 

          FMenuItem.ImageIndex   :=   TPopupMenu(AMenu).Images.Count   -   1; 

          FMenuItem.Caption   :=   ‘導出(&E)’; 

          FMenuItem.OnClick   :=   Self.miExportClick; 

          TPopupMenu(AMenu).Items.Add(FMenuItem); 

          //列印

          FMenuItem   :=   TMenuItem.Create(Self); 

          FMenuItem.Name   :=   ‘miPrint’; 

          FMenuItem.Caption   :=   ‘列印(&P)’; 

          TPopupMenu(AMenu).Images.AddImage(FormMain.ImageListExtend,   14); 

          FMenuItem.ImageIndex   :=   TPopupMenu(AMenu).Images.Count   -   1; 

          FMenuItem.OnClick   :=   Self.miPrintClick; 

          TPopupMenu(AMenu).Items.Add(FMenuItem); 

      end; 

  end; 

  procedure   TFormItemList.miExportClick(Sender:   TObject); 

  var 

      FileName,   FileExt,   msg:   String; 

  begin 

      if   Self.aqyQuery.IsEmpty   then 

      begin 

          msg   :=   ‘沒有導出資料…’; 

          Application.MessageBox(PChar(msg),   PChar(Application.Title), 

              MB_OK   or   MB_IconWarning); 

          Exit; 

      end; 

      Self.SaveDialogExport.Filter   :=   ‘Excel文件   (*.xls)|*.xls|XML文件   (*.xml)|*.xml’ 

          +   ‘|文字檔案   (*.txt)|*.txt|網頁文件   (*.html)|*.html’; 

      Self.SaveDialogExport.Title   :=   ‘導出為’; 

      if   not   Self.SaveDialogExport.Execute   then 

          Exit; 

      FileName   :=   Self.SaveDialogExport.FileName; 

      FileExt   :=   LowerCase(ExtractFileExt(FileName)); 

      if   FileExt   =   ‘.xls’   then 

          ExportGrid4ToExcel(FileName,   Self.cxGrid1) 

      else   if   FileExt   =   ‘.xml’   then 

          ExportGrid4ToXML(FileName,   Self.cxGrid1) 

      else   if   FileExt   =   ‘.txt’   then 

          ExportGrid4ToText(FileName,   Self.cxGrid1) 

      else   if   FileExt   =   ‘.html’   then 

          ExportGrid4ToHTML(FileName,   Self.cxGrid1) 

      else 

      begin 

          msg   :=   ‘不支援的導出檔類型…’; 

          Application.MessageBox(PChar(msg),   PChar(Application.Title), 

              MB_OK   or   MB_IconError); 

          Exit; 

      end; 

      msg   :=   ‘導出完成…’; 

      Application.MessageBox(PChar(msg),   PChar(Application.Title), 

          MB_OK   or   MB_IconInformation); 

  end; 

  procedure   TFormItemList.miPrintClick(Sender:   TObject); 

  begin 

      //列印

      Self.dxComponentPrinter.Preview(True,   Self.dxComponentPrinterLink1); 

  end; 

  procedure   TFormItemList.cxGridPopupMenuPopup(ASenderMenu:   TComponent; 

      AHitTest:   TcxCustomGridHitTest;   X,   Y:   Integer;   var   AllowPopup:   Boolean); 

  begin 

      if   GetHitTypeByHitCode(AHitTest.HitTestCode)   =   gvhtColumnHeader   then //右擊列標題時

      begin 

          //if   tvResult.DataController.Groups.GroupingItemCount   >   0   then 

          if   tvResult.GroupedColumnCount   >   0   then //有分組時顯示

          begin 

            TMenuItem(Self.FindComponent(‘miLineForGroup’)).Visible   :=   True; 

            TMenuItem(Self.FindComponent(‘miExpandAllGroup’)).Visible   :=   True; 

            TMenuItem(Self.FindComponent(‘miCollapseAllGroup’)).Visible   :=   True; 

          end 

          else 

          begin 

            TMenuItem(Self.FindComponent(‘miLineForGroup’)).Visible   :=   False; 

            TMenuItem(Self.FindComponent(‘miExpandAllGroup’)).Visible   :=   False; 

            TMenuItem(Self.FindComponent(‘miCollapseAllGroup’)).Visible   :=   False; 

          end; 

      end; 

  end; 

  procedure   TFormItemList.miFilterBuilderClick(Sender:   TObject); 

  begin 

      //過濾管理器

      //彈出Filter   Builder   Dialog對話方塊

      tvResult.Filtering.RunCustomizeDialog; 

  end; 

  procedure   TFormItemList.miCustomFilterClick(Sender:   TObject); 

  var 

      AHitTest:   TcxCustomGridHitTest; 

  begin 

      //自定義過濾

      //彈出Custom   Filter   Dialog對話方塊

      AHitTest   :=   cxGridPopupMenu.HitTest; 

      if   GetHitTypeByHitCode(AHitTest.HitTestCode)   =   gvhtColumnHeader   then //獲得右擊的列

          tvResult.Filtering.RunCustomizeDialog(TcxGridColumnHeaderHitTest(AHitTest).Column); 

  end; 

  procedure   TFormItemList.miFilterPanelClick(Sender:   TObject); 

  var 

      mi:   TMenuItem; 

  begin 

      //隱藏/顯示過濾面板

      mi   :=   TMenuItem(Sender); 

      mi.Checked   :=   True; 

      if   mi.Name   =   ‘miFilterPanelAlways’   then 

          tvResult.Filtering.Visible   :=   fvAlways 

      else   if   mi.Name   =   ‘miFilterPanelNerver’   then 

          tvResult.Filtering.Visible   :=   fvNever 

      else 

          tvResult.Filtering.Visible   :=   fvNonEmpty; 

  end; 

  procedure   TFormItemList.miExpandAllGroupClick(Sender:   TObject); 

  begin 

      //展開所有組

      tvResult.DataController.Groups.FullExpand; 

  end; 

  procedure   TFormItemList.miCollapseAllGroupClick(Sender:   TObject); 

  begin 

      //收縮所有組

      tvResult.DataController.Groups.FullCollapse; 

  end; 

此樓回復Re:


在用,留名

此樓回復Re:


技巧三 按條件計算合計值

在Footer的第一列顯示[合計:] 

加一個Summary項,Column設為Grid的第一列,Kind設為skNone 

在該Summary項的OnGetText事件中,輸入: 

  procedure   TFormExpense.tvExpenseTcxGridDBDataControllerTcxDataSummaryFooterSummaryItems2GetText( 

      Sender:   TcxDataSummaryItem;   const   AValue:   Variant;   AIsFooter:   Boolean; 

      var   AText:   String); 

  begin 

      AText   :=   ‘合計:’; 

  end; 

按條件匯總: 

在TableView的DataController->Summary->FooterSummary->OnSummary事件中,輸入: 

  procedure   TFormExpense.tvExpenseDataControllerSummaryFooterSummaryItemsSummary( 

      ASender:   TcxDataSummaryItems;   Arguments:   TcxSummaryEventArguments; 

      var   OutArguments:   TcxSummaryEventOutArguments); 

  begin 

      //得到欄位名   TcxDBDataSummaryItem(Arguments.SummaryItem).FieldName; 

      if   (ASender.DataController.Values[Arguments.RecordIndex,   tvExpenseLevel.Index]   >   1)       //只統計Level列=1的值

          and   (TcxDBDataSummaryItem(Arguments.SummaryItem).Kind   =   skSum)   then 

          OutArguments.Value   :=   0; //Level   >   1的統計值設為0 

  end; 

此樓回復Re:


借貴地一用,問個CXGrid問題,在cxgrid中如何使一些行不能編輯,如:欄位isenable   =   false的行

此樓回復Re:


樓上的問題

請參考下面的技巧

技巧四:根據某列的值設定其他列的可編輯性

  procedure   TFormUser.tvUserEditing(Sender:   TcxCustomGridTableView; 

      AItem:   TcxCustomGridTableItem;   var   AAllow:   Boolean); 

  begin 

      //如果第三列值為True,則第4列不能修改

      if   (tvUser.Controller.FocusedRecord.Values[2]   =   True)   and   (AItem.Index   =   4)   then 

          AAllow   :=   False 

      else 

          AAllow   :=   True; 

  end; 

此樓回復Re:


技巧五:保存/恢復Grid佈局

  //恢復佈局

  IniFileName   :=   ExtractFilePath(Application.ExeName)   +   ‘Layout\’   +   Self.Name   +   ‘.ini’; 

  if   FileExists(IniFileName)   then 

      Self.tvResult.RestoreFromIniFile(IniFileName) //從佈局檔中恢復

  else 

  begin 

      Self.tvResult.BeginUpdate; 

      for   i   :=   0   to   Self.tvResult.ItemCount   -   1   do 

          Self.tvResult.Items[i].ApplyBestFit; //調整為最佳寬度

      Self.tvResult.EndUpdate; 

  end; 

  //保存佈局

  IniFileName   :=   ExtractFilePath(Application.ExeName)   +   ‘Layout\’   +   Self.Name   +   ‘.ini’; 

  if   not   DirectoryExists(ExtractFileDir(IniFileName))   then 

      CreateDir(ExtractFileDir(IniFileName)); 

  Self.tvResult.StoreToIniFile(IniFileName); //保存為佈局檔

此樓回復Re:


借用地問一下:在   cxgrid中,如果我同時選中主表與子表中的記錄,怎么樣能同時進行對其所選記錄進行處理呢。

我現在只能判斷 焦點是在主表還是從表中,然後只能對主表或子表中的資料進行處理。

此樓回復Re:


看來用cxGrid人不多啊

再多貼一些技巧,需要的朋友頂一下

  ========================================================================== 

在主從TableView中根據主TableView得到對應的從TableView 

  var 

      ADetailDC:   TcxGridDataController; 

      AView:   TcxCustomGridTableView; 

  begin 

      with   cxGrid1DBTableView1.DataController   do 

          ADetailDC   :=   TcxGridDataController(GetDetailDataController(FocusedRecordIndex,   0)); 

      AView   :=   ADetailDC.GridView; 

  end; 

  ============================================================================== 

定位在第一行並顯示內置編輯器

  cxDBVerticalGrid1.FocusedRow   :=   cxDBVerticalGrid1.Rows[0]; 

  cxDBVerticalGrid1.ShowEdit; 

  ============================================================================== 

隱藏   "<No   data   to   display>"   字串

該文本存儲在scxGridNoDataInfoText資源字串,可以將該資源字串的內容設為空

來隱藏該文本。

  uses   cxClasses,   cxGridStrs;   

      … 

      cxSetResourceString(@scxGridNoDataInfoText,   ”); 

      //如果"<No   data   to   display>"   字串已經顯示,需要調用:

      <View>.LayoutChanged; 

  ============================================================ 

刪除應用過濾後的行

  var 

      I:   Integer; 

  begin 

      with   <GridView>   do 

          for   I   :=   0   to   ViewData.RecordCount   -   1   do 

          begin 

              ViewData.Records[0].Focused   :=   True; 

              DataController.DataSet.Delete; 

          end; 

  ============================================================= 

根據單元的值設置樣式

  procedure   <aForm>.<aColumn>StylesGetContentStyle( 

      Sender:   TcxCustomGridTableView;   ARecord:   TcxCustomGridRecord; 

      AItem:   TcxCustomGridTableItem;   out   AStyle:   TcxStyle); 

  begin 

      if   ARecord.Values[AItem.Index]   =   aSomeValue   then 

          AStyle   :=   <aSomeStyle>; 

  end; 

  procedure   <aForm>.<aView>StylesGetContentStyle( 

      Sender:   TcxCustomGridTableView;   ARecord:   TcxCustomGridRecord; 

      AItem:   TcxCustomGridTableItem;   out   AStyle:   TcxStyle); 

  var 

      AColumn:   TcxCustomGridTableItem; 

  begin 

      AColumn   :=   (Sender   as   TcxGridDBTableView).GetColumnByFieldName(‘Email’); 

      if   VarToStr(ARecord.Values[AColumn.Index])   =   ”   then 

          AStyle   :=   cxStyleNullEmail; 

  end; 

  ============================================================================== 

  TcxCustomGridTableView.FindItemByName,   TcxGridDBTableView.GetColumnByFieldName   or 

  TcxGridDBDataController.GetItemByFieldName 

      with   cxGrid1DBBandedTableView1.DataController   do 

          AValue   :=   Values[FocusedRecordIndex,   GetItemByFieldName(‘SomeFieldName’).Index]; 

  =================================================================== 

動態生成BandedView 

  var 

      AView:   TcxCustomGridView; 

  begin 

      AView   :=   <cxGrid>.CreateView(TcxGridDBBandedTableView); 

      TcxGridDBBandedTableView(AView).DataController.DataSource   :=   <DataSource>; 

      TcxGridDBBandedTableView(AView).Bands.Add; 

      with   TcxGridDBBandedTableView(AView).Bands.Add   do 

      begin 

          Visible   :=   False; 

          FixedKind   :=   fkLeft; 

      end; 

      TcxGridDBBandedTableView(AView).DataController.CreateAllItems; 

      <cxGridLevel>.GridView   :=   AView; 

此樓回復Re:


====================================================================== 

當底層資料集為空時顯示一條空記錄

  procedure   <Form>.<cxGrid>Enter(Sender:   TObject); 

  var 

      View:   TcxGridDBTableView; 

  begin 

      View   :=   TcxGridDBTableView((Sender   as   TcxGrid).FocusedView); 

      if   View.DataController.DataSet.IsEmpty   then 

      begin 

          View.DataController.DataSet.Append; 

          View.Controller.EditingController.ShowEdit; 

      end; 

  end; 

  ======================================================================= 

在當前View插入記錄

使用FocusedView屬性得到當前焦點View,用View.DataController得到對應的Data   Controller,

之後使用Data   Controller的方法來運算元據:

  -   Append 

  -   Insert 

  -   Post 

  -   Cancel 

  -   DeleteFocused 

  -   DeleteSelection 

示例:

  var 

      ARecIndex:   Integer; 

  … 

      View.DataController.Append; 

      ARecIndex   :=   View.DataController.FocusedRecordIndex; 

      View.DataController.Values[ARecIndex,   SomeItemIndex]   :=   SomeValue; 

      View.DataController.Post; 

另外一種方法是使用View.DataController.DataSource.DataSet得到底層資料集後,再用資料集的

方法來運算元據。

  ======================================================================== 

啟動內置編輯控制項

    1)   <aView>.Controller.EditingController.ShowEdit(<aColumn>); 

    2)   <aView>.Controller.EditingController.StartEditShowingTimer(<aColumn>); 

    3)   <aView>.Controller.EditingItem   :=   <aColumn>; 

    4)   <aColumn>.Editing   :=   True; 

隱藏內置編輯控制項

      <aView>.Controller.EditingController.HideEdit(True); 

  =========================================================================== 

移除一個分組列

      <aColumn>.GroupIndex   :=   -1; 

      <aColumn>.Visible   :=   True; 

  =========================================================================== 

保存修改到資料庫

  procedure   <aForm>.FormClose(Sender:   TObject;   var   Action:   TCloseAction); 

  begin 

      if   (<aGrid>.FocusedView   <>   nil)   and   (<aGrid>.FocusedView.DataController.EditState   <>   [])   then 

          <aGrid>.FocusedView.DataController.Post; 

  end; 

  ============================================================================ 

設置內置右鍵菜單

內置右鍵功能表包括二個功能表:cxGridStdHeaderMenu,   TcxGridStdFooterMenu 

  uses   cxGridStdPopupMenu; 

  procedure   TForm1.cxGridPopupMenu1Popup(ASenderMenu:   TComponent; 

      AHitTest:   TcxCustomGridHitTest;   X,   Y:   Integer;   var   AllowPopup:   Boolean); 

  begin 

      if   ASenderMenu   is   TcxGridStdHeaderMenu   then 

          TcxGridStdHeaderMenu(ASenderMenu).OnPopup   :=   StdHeaderMenuPopup; 

  end; 

  procedure   TForm1.StdHeaderMenuPopup(Sender:   TObject); 

  var 

      I:   Integer; 

  begin 

      with   TcxGridStdHeaderMenu(Sender).Items   do 

          for   I   :=   0   to   Count   -   1   do 

              if   Items[I].Caption   =   ‘Group   By   Box’   then 

              begin 

                  Items[I].Enabled   :=   False; 

                  System.Break; 

              end 

  end; 

  =========================================================================== 

得到選中記錄的值(MultiSelect) 

  1)   View.DataController.DataModeController.GridMode   =   False時

      RecIdx   :=   View.Controller.SelectedRecords[i].RecordIndex; 

      ColIdx   :=   View.DataController.GetItemByFieldName(AFieldName).Index; 

      OutputVal   :=   View.DataController.Values[RecIdx,   ColIdx]; 

      //RecID   :=   View.DataController.GetRecordId(RecIdx); 

      //OutputVal   :=   ADataSet.Lookup(View.DataController.KeyFieldNames,   RecID,   AFieldName); 

  2)   Bkm: string; 

View.DataController.DataModeController.GridMode   =   True時

      Bkm   :=   View.DataController.GetSelectedBookmark(ASelectedRecordIndex); 

      if   ADataSet.BookmarkValid(TBookmark(Bkm))   then 

      begin 

          ADataSet.Bookmark   :=   Bkm; 

          OutputVal   :=   ADataSet.FieldByName(AFieldName).Value; 

      end; 

      View.BeginUpdate; 

      View.DataController.BeginLocate; 

      try 

          //   make   changes   here… 

      finally 

          View.DataController.EndLocate; 

          View.EndUpdate; 

      end; 

    //直接讀取選擇的單格內容

var

I, J: Integer;

val: Variant;

begin

Result := 0;

for I := 0 to TableView.Controller. SelectedRowCount – 1 do

for J := 0 to TableView.Controller. SelectedColumnCount – 1 do

begin

val := TableView.DataController.GetValue(

TableView.Controller.SelectedRows[I].RecordIndex,

TableView.Controller.SelectedColumns[J].Index);

Showmessage(val);

end;

end;

  ============================================================= 

在GridMode禁用內置的右鍵Footer菜單

  uses   cxGridStdPopupMenu; 

  procedure   cxGridPopupMenuOnPopup(…) 

  begin 

      if   (ASenderMenu   is   TcxGridStdFooterMenu)   and 

              <GridView>.DataController.DataModeController.GridMode   then 

          AllowPopup   :=   False; 

  end; 

  ============================================================== 

主從表任何時候只能展開一個組

  procedure   TForm1.ADetailDataControllerCollapsing( 

      ADataController:   TcxCustomDataController;   ARecordIndex:   Integer; 

      var   AAllow:   Boolean); 

  var 

      I:   Integer; 

      C:   Integer; 

  begin 

      AAllow   :=   False; 

      C   :=   0; 

      for   I   :=   0   to   ADataController.RecordCount   -   1   do 

      begin 

          if   ADataController.GetDetailExpanding(I)   then 

              Inc(C); 

          if   C   >   1   then 

              AAllow   :=   True; 

        end; 

  end; 

  procedure   TForm1.ADetailDataControllerExpanding( 

      ADataController:   TcxCustomDataController;   ARecordIndex:   Integer; 

      var   AAllow:   Boolean); 

  begin 

      ADataController.CollapseDetails; 

  end; 

  procedure   TForm1.FormCreate(Sender:   TObject); 

  begin 

      cxGrid1DBTableView1.DataController.OnDetailExpanding   :=   ADetailDataControllerExpanding; 

      cxGrid1DBTableView1.DataController.OnDetailCollapsing   :=   ADetailDataControllerCollapsing; 

  end; 

  ================================================================= 

動態創建層次(Level)和視圖(View) 

  var     

      Grid:   TcxGrid;     

      Level:   TcxGridLevel;     

      View:   TcxGridDBTableView;     

  begin 

      //   Creates   a   Grid   instance 

      Grid   :=   TcxGrid.Create(SomeOwner);     

      Grid.Parent   :=   SomeParent;     

      //   Creates   a   Level 

      Level   :=   Grid.Levels.Add;     

      Level.Name   :=   ‘SomeLevelName’; 

      //   Creates   a   View 

      View   :=   Grid.CreateView(TcxGridDBTableView)   as   TcxGridDBTableView;     

      View.Name   :=   ‘SomeViewName’; 

      //   …   and   binds   it   to   the   Level 

      Level.GridView   :=   View;     

      //   Hooks   up   the   View   to   the   data 

      View.DataController.DataSource   :=   SomeDataSource;     

      //   …   and   creates   all   columns 

      View.DataController.CreateAllItems;     

  end;   

此樓回復Re:


====================================================================== 

獲得Group   Footer合計行對應的記錄

  procedure   TForm1.cxGrid1DBTableView1CustomDrawFooterCell( 

      Sender:   TcxGridTableView;   ACanvas:   TcxCanvas; 

      AViewInfo:   TcxGridColumnHeaderViewInfo;   var   ADone:   Boolean); 

  var 

      ALevel,   ADataGroupIndex:   Integer; 

      AGridRecord,   AGroupRecord:   TcxCustomGridRecord; 

  begin 

      if   AViewInfo   is   TcxGridRowFooterCellViewInfo   and       //   Row   footer 

            (TcxGridDBColumn(AViewInfo.Column).DataBinding.FieldName   =   ‘Area’)   then     //   Area   column 

          begin 

              AGridRecord   :=   TcxGridRowFooterCellViewInfo(AViewInfo).GridRecord; 

              ALevel   :=   TcxGridRowFooterCellViewInfo(AViewInfo).Container.GroupLevel; 

              ADataGroupIndex   :=   Sender.DataController.Groups.DataGroupIndexByRowIndex[AGridRecord.Index]; 

              if   ADataGroupIndex   <>   -1   then 

              begin 

                  AGroupRecord   :=   AGridRecord; 

                  while   AGroupRecord.Level   <>   ALevel   do 

                      AGroupRecord   :=   AGroupRecord.ParentRecord; 

                  AViewInfo.Text   :=   AGroupRecord.DisplayTexts[0]; 

              end; 

          end; 

  end; 

  =========================================================================== 

訪問過濾之後的記錄

  var 

      I:   Integer; 

  begin 

      Memo1.Lines.Clear; 

      with   cxGrid1DBTableView1.DataController   do 

          for   I   :=   0   to   FilteredRecordCount   -   1   do 

              Memo1.Lines.Add(DisplayTexts[FilteredRecordIndex[I],   0]); 

  end; 

  ============================================================================ 

獲得單元的Font 

  cxGrid1DBTableView1.ViewInfo.RecordsViewInfo.Items[1].GetCellViewInfoByItem( 

      cxGrid1DBTableView1Company).EditViewInfo.Font; 

  ============================================================================ 

根據Level名稱找到Level物件

  function   GetLevelByName(AGrid:   TcxGrid;   ALevelName:   string):   TcxGridLevel; 

      function   LoopThroughLevels(ALevel:   TcxGridLevel;   ALevelName:   string):   TcxGridLevel; 

      var 

          I:   Integer; 

      begin 

          Result   :=   nil; 

          for   I   :=   0   to   ALevel.Count   -   1   do 

          begin 

              if   ALevel[I].Name   =   ALevelName   then 

              begin 

                  Result   :=   ALevel[I]; 

                  Exit; 

              end; 

              if   ALevel[I].Count   >   0   then 

              begin 

                  Result   :=   LoopThroughLevels(ALevel[I],   ALevelName); 

                  if   Result   <>   nil   then 

                      Exit; 

              end; 

          end; 

      end; 

  var 

      I:   Integer; 

  begin 

      Result   :=   nil; 

      for   I   :=   0   to   AGrid.Levels.Count   -   1   do 

      begin 

          if   AGrid.Levels[I].Name   =   ALevelName   then 

          begin 

              Result   :=   AGrid.Levels[I]; 

              Exit; 

          end; 

          if   AGrid.Levels[I].Count   >   0   then 

          begin 

              Result   :=   LoopThroughLevels(AGrid.Levels[I],   ALevelName); 

              if   Result   <>   nil   then 

                  Exit; 

          end; 

      end; 

  end; 

  ============================================================================ 

指定Filter   Builder打開/保存過濾檔的默認路徑

  uses 

      …,   cxFilterControlDialog; 

  procedure   TForm.GridView1FilterControlDialogShow( 

      Sender:   TObject); 

  begin 

      TfmFilterControlDialog(Sender).OpenDialog.InitialDir   :=   ‘D:\’ 

  end;   

  ============================================================================ 

保存/恢復帶匯總行的佈局

  <TableView>.StoreToIniFile(‘c:\Grid.ini’,   True,   [gsoUseSummary]);   

  <GridView>.RestoreFromIniFile(<inifilename>,True,False   {or   True,   optional},[gsoUseSummary]); 

  ============================================================================ 

取消過濾時移到第一行

  uses 

      cxCustomData; 

  procedure   TYour_Form.AViewDataControllerFilterChanged(Sender:   TObject); 

  var 

      Filter:   TcxDataFilterCriteria; 

  begin 

      with   Sender   as   TcxDataFilterCriteria   do 

          if   IsEmpty   then 

              DataController.FocusedRowIndex   :=   0; 

  end; 

  ============================================================================= 

排序後移到第一行

可以設置DataController.Options.FocusTopRowAfterSorting   :=   True,也可以使用如下的代碼:

  uses 

      cxCustomData; 

  procedure   TYour_Form.Your_ViewDataControllerSortingChanged(Sender:   TObject); 

  begin 

      TcxCustomDataController(Sender).FocusedRowIndex   :=   0; 

  end; 

  ============================================================================== 

判斷當前行是否第一行或最後一行

可以使用DataController的IsBOF,   IsEOF方法,或者:

  <AView>.Controller.Controller.FocusedRow.IsFirst 

  <AView>.Controller.Controller.FocusedRow.IsLast 

  ============================================================================== 

根據指定值查找記錄

  DataController提供了好幾個方法來得到指定值對應的RecordIndex 

對於Bound   View可以使用FindRecordIndexByKeyValue方法

  =============================================================================== 

編輯和顯示Blob欄位

該欄位的Properties設置為BlobEdit,並將BlobPaintStyle   屬性設為   bpsText 

  =============================================================================== 

得到可見行數

  <View>.ViewInfo.VisibleRecordCount 

  =============================================================================== 

保存後的行設置為當前行

  const 

      CM_SETFOCUSEDRECORD   =   WM_USER   +   1002; 

  type 

      TForm1   =   class(TForm) 

          cxGrid1DBTableView1:   TcxGridDBTableView; 

          cxGrid1Level1:   TcxGridLevel; 

          cxGrid1:   TcxGrid; 

          dxMemData1:   TdxMemData; 

          dxMemData1Field1:   TStringField; 

          dxMemData1Field2:   TIntegerField; 

          DataSource1:   TDataSource; 

          cxGrid1DBTableView1RecId:   TcxGridDBColumn; 

          cxGrid1DBTableView1Field1:   TcxGridDBColumn; 

          cxGrid1DBTableView1Field2:   TcxGridDBColumn; 

          Timer1:   TTimer; 

          CheckBox1:   TCheckBox; 

          procedure   Timer1Timer(Sender:   TObject); 

          procedure   dxMemData1AfterPost(DataSet:   TDataSet); 

          procedure   CheckBox1Click(Sender:   TObject); 

      private 

          procedure   CMSetFocusedRecord(var   Msg:   TMessage);   message   CM_SETFOCUSEDRECORD; 

      public 

          {   Public   declarations   } 

      end; 

  var 

      Form1:   TForm1; 

      FocusedIdx:   Integer; 

  implementation 

  {$R   *.dfm} 

  procedure   TForm1.Timer1Timer(Sender:   TObject); 

  begin 

      dxMemData1.AppendRecord([”,   IntToStr(Random(1000)),   Random(1000)]); 

  end; 

  procedure   TForm1.dxMemData1AfterPost(DataSet:   TDataSet); 

  begin 

      PostMessage(Handle,   CM_SETFOCUSEDRECORD,   Integer(cxGrid1DBTableView1),   MakeLParam(cxGrid1DBTableView1.Controller.FocusedRowIndex,   cxGrid1DBTableView1.Controller.TopRowIndex)); 

  end; 

  procedure   TForm1.CMSetFocusedRecord(var   Msg:   TMessage); 

  begin 

      TcxGridDBTableView(msg.WParam).Controller.FocusedRowIndex   :=   Msg.LParamLo; 

      TcxGridDBTableView(msg.WParam).Controller.TopRowIndex   :=   Msg.LParamHi; 

  end; 

  procedure   TForm1.CheckBox1Click(Sender:   TObject); 

  begin 

      Timer1.Enabled   :=   TCheckBox(Sender).Checked; 

  end; 

  end. 

  ================================================================================= 

刪除記錄並獲得焦點

  procedure   TForm1.BtnDeleteClick(Sender:   TObject); 

  var 

      FocusedRow,   TopRow:   Integer; 

      View:   TcxGridTableView; 

      DataController:   TcxGridDataController; 

  begin 

      View   :=   cxGrid1.FocusedView   as   TcxGridTableView; 

      DataController   :=   View.DataController; 

      //   Remember   the   top   row   (the   vertical   scrollbar   position) 

      TopRow   :=   View.Controller.TopRowIndex; 

      //   Remember   the   focused   row(!)   index 

      FocusedRow   :=   DataController.FocusedRowIndex; 

      DataController.DeleteFocused; 

      //   After   deletion   the   same   row   must   be   focused, 

      //   although   it   will   correspond   to   a   different   data   record 

      DataController.FocusedRowIndex   :=   FocusedRow; 

      //   Restore   the   top   row 

      View.Controller.TopRowIndex   :=   TopRow; 

  end; 

//====================================================================================

報表匯總的設置

資料庫中的財務表為:

      ID     收支類型 金額 其他屬性

其中收支類型只有兩種值:0   表示收入,1   表示支出 ;金額都是正數。

設置cxGrid的Footer   可以使得在顯示時,列表的下方出現匯總行:“金額”的和

同樣設置Default   For   Groups可以使得在用戶拖動表頭屬性實現分組時,顯示組內的匯總行:“金額”的和。

上面說的,用過cxGrid應該都會,下面就有這么一個問題

如果我想使匯總行的值變為如下的值應該怎樣實現:

收支類型為0的金額的和   -   收支類型為1的金額的和

實現Footer的功能好辦,因為它的值不會變,自己用迴圈寫一個就完了,但是Default   For   Groups的功能就不好說了,因為它的值是根據用戶拖動的屬性計算的,而且還有可能是多層分組,想不出來了,所有到這來問

是不是要設置什么屬性?或者cxGrid根本就沒這個功能,那該用什么方法解決?希望哪位幫我解決,謝謝了先!

給你一個例子,可能對你有幫助, 

    with   tvOrders.DataController.Summary   do 

      begin 

          BeginUpdate; 

          try 

              SummaryGroups.Clear; 

              //The   first   summary   group 

              with   SummaryGroups.Add   do 

              begin 

                  //Add   proposed   grouping   column(s) 

                  TcxGridTableSummaryGroupItemLink(Links.Add).Column   :=   tvOrdersCustomerID; 

                  //Add   summary   items 

                  with   SummaryItems.Add   as   TcxGridDBTableSummaryItem   do 

                  begin 

                      Column   :=   tvOrdersPaymentAmount; 

                      Kind   :=   skSum; 

                      Format   :=   ‘Amount   Paid:   $,0’; 

                  end; 

                  with   SummaryItems.Add   as   TcxGridDBTableSummaryItem   do 

                  begin 

                      Column   :=   tvOrdersPaymentAmount; 

                      Kind   :=   skCount; 

                      Format   :=   ‘Records:   0’; 

                  end; 

              end; 

              //The   second   summary   group 

              with   SummaryGroups.Add   do 

              begin 

                  //Add   proposed   grouping   column(s) 

                  TcxGridTableSummaryGroupItemLink(Links.Add).Column   :=   tvOrdersProductID; 

                  //Add   summary   items 

                  with   SummaryItems.Add   as   TcxGridDBTableSummaryItem   do 

                  begin 

                      Column   :=   tvOrdersQuantity; 

                      Kind   :=   skSum; 

                      Position   :=   spFooter; 

                      Format   :=   ‘TOTAL   =   0’; 

                  end; 

                  with   SummaryItems.Add   as   TcxGridDBTableSummaryItem   do 

                  begin 

                      Column   :=   tvOrdersPurchaseDate; 

                      Kind   :=   skMin; 

                      Position   :=   spFooter; 

                  end; 

              end; 

          finally 

              EndUpdate; 

          end; 

      end;   

2007-7-19 12:56:41    go on

訂單號 商品名 單價 數量 金額

001 aa 11.00 2 22.00

001 bb 2.00 2 4.00

001 cc 3.00 3 9.00

———————-合計 7 35.00

002 ee 11.00 2 22.00

002 bb 3.00 2 6.00

002 cc 3.00 3 9.00

———————-合計 7 37.00

總計14 72.00

每個單號分一個小結,能實現嗎?最後在底下實現總的合計

可以的,cxGrid的功能比你想像的還要強大。

1.你先放一個cxGrid,設置好View,設置View.DataController連接的DataSource

2.啟動DataSource連接的DataSet,雙擊cxGrid,點擊Retrieve Fields,取得所有的Column

3.設置View的OptionsView.Footer=True,OptionsView.GroupFooters=True,這是為了把分組小計和總計面板顯示出來

4.將“訂單號”欄位拖到cxGrid上方的分組面板(GroupbyBox),將資料按“訂單號”分組。這時你會發現單身所有的資料都縮起來了,如果想使所有的資料都展開,可以設置View.DataController.Options.dcoGroupsAlwaysExpanded=True

5.設置分組小計:把View.DataController.Summary.DefaultGroupSummaryItems點開,新增一個Item,Column屬性在下拉裏選擇“數量”欄位,FieldName屬性為空,Format屬性可以設置數值的顯示格式,Kind屬性下拉skSum加總,Position屬性一定要選擇spFooter。

6.設置總計:把View.DataController.Summary.FooterSummaryItems點開,新增一個Item,Column屬性在下拉裏選擇“數量”欄位,FieldName屬性為空,Format屬性可以設置數值的顯示格式,Kind屬性下拉skSum加總,Position屬性一定要選擇spFooter。

大功告成,按F9看一下勝利果實吧。

再奉送一個技巧,在Form1再放一個TcxGridPopupMenu控制項,就在cxGrid控制項旁邊的那個,把TcxGridPopupMenu的Grid屬性設置成你的cxGrid。

然後運行程式,在運行狀態,點擊Grid上的所有地方,左鍵或右鍵,你都會有意外收穫。

ExpressQuantumGrid控制項實在是太複雜,太龐大,最好的瞭解它的方法就是查幫助。

cxGrid的多選我一般都是用這個方法:

//————— .Pas文件

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, cxStyles, cxCustomData, cxGraphics, cxFilter, cxData, cxEdit,

DB, cxDBData, DBTables, cxGridLevel, cxGridCustomTableView,

cxGridTableView, cxGridDBTableView, cxClasses, cxControls,

cxGridCustomView, cxGrid, cxLookAndFeelPainters, cxGridRows, cxContainer,

cxCheckBox, cxDataStorage;

type

TForm1 = class(TForm)

cxGrid1: TcxGrid;

cxGrid1DBTableView1: TcxGridDBTableView;

cxGrid1DBTableView1CustNo: TcxGridDBColumn;

cxGrid1DBTableView1Company: TcxGridDBColumn;

cxGrid1DBTableView1Addr1: TcxGridDBColumn;

cxGrid1DBTableView1City: TcxGridDBColumn;

cxGrid1DBTableView1State: TcxGridDBColumn;

cxGrid1DBTableView1Country: TcxGridDBColumn;

cxGrid1Level1: TcxGridLevel;

Table1: TTable;

DataSource1: TDataSource;

cxGrid1DBTableView1DBColumn1: TcxGridDBColumn;

procedure FormCreate(Sender: TObject);

procedure cxGrid1DBTableView1MouseDown(Sender: TObject;

Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

procedure cxGrid1DBTableView1DBColumn1CustomDrawCell(

Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;

AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);

procedure FormClose(Sender: TObject; var Action: TCloseAction);

procedure cxGrid1DBTableView1CustomDrawCell(

Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;

AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);

private

AList: TList;

function CheckList(ARecord: TcxCustomGridRecord): Boolean;

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);

begin

AList := TList.Create;

end;

function TForm1.CheckList(ARecord: TcxCustomGridRecord): Boolean;

begin

Result := AList.IndexOf(Pointer(ARecord.RecordIndex)) <> – 1;

end;

procedure TForm1.cxGrid1DBTableView1MouseDown(Sender: TObject;

Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

var

AHitTest: TcxCustomGridHitTest;

AGridRecord: TcxCustomGridRecord;

begin

if Sender is TcxGridSite then

begin

with TcxGridSite(Sender).GridView do

AHitTest := ViewInfo.GetHitTest(X, Y);

if (AHitTest.HitTestCode = htCell) and (TcxGridDBColumn(TcxGridRecordCellHitTest (AhitTest). Item ). DataBinding . FieldName = ) then

AGridRecord := TcxGridRecordCellHitTest(AHitTest).GridRecord

else

Exit;

end;

if (AGridRecord <> nil) then

if CheckList(AGridRecord) then

AList.Remove(Pointer(AGridRecord.RecordIndex))

else

AList.Add(Pointer(AGridRecord.RecordIndex));

end;

procedure TForm1.cxGrid1DBTableView1DBColumn1CustomDrawCell(

Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;

AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);

begin

if AViewInfo.EditViewInfo is TcxCustomCheckBoxViewInfo then

TcxCustomCheckBoxViewInfo(AViewInfo.EditViewInfo).State:= TcxCheckBoxState(CheckList(AViewInfo.GridRecord));

end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

begin

AList.Free;

end;

procedure TForm1.cxGrid1DBTableView1CustomDrawCell(

Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;

AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);

begin

with AViewInfo do

if CheckList(GridRecord) then

ACanvas.Brush.Color := clHighlight

else

ACanvas.Brush.Color := clWindow;

ACanvas.Font.Color := clBlack;

end;

end.

//—————cxGrid的Dfm屬性

object cxGrid1: TcxGrid

Left = 0

Top = 0

Width = 688

Height = 446

Align = alClient

TabOrder = 0

object cxGrid1DBTableView1: TcxGridDBTableView

OnMouseDown = cxGrid1DBTableView1MouseDown

NavigatorButtons.ConfirmDelete = False

OnCustomDrawCell = cxGrid1DBTableView1CustomDrawCell

DataController.DataSource = DataSource1

DataController.DetailKeyFieldNames = CustNo

DataController.KeyFieldNames = CustNo

DataController.Summary.DefaultGroupSummaryItems = <>

DataController.Summary.FooterSummaryItems = <>

DataController.Summary.SummaryGroups = <>

OptionsSelection.MultiSelect = True

object cxGrid1DBTableView1CustNo: TcxGridDBColumn

DataBinding.FieldName = CustNo

end

object cxGrid1DBTableView1DBColumn1: TcxGridDBColumn

Caption = CheckColumn

PropertiesClassName = TcxCheckBoxProperties

Properties.DisplayUnchecked = False

OnCustomDrawCell = cxGrid1DBTableView1DBColumn1CustomDrawCell

Options.Editing = False

Options.Filtering = False

Options.IncSearch = False

Options.ShowEditButtons = isebNever

Options.Grouping = False

Options.Sorting = False

Width = 123

end

object cxGrid1DBTableView1Company: TcxGridDBColumn

DataBinding.FieldName = Company

end

object cxGrid1DBTableView1Addr1: TcxGridDBColumn

DataBinding.FieldName = Addr1

end

object cxGrid1DBTableView1City: TcxGridDBColumn

DataBinding.FieldName = City

end

object cxGrid1DBTableView1State: TcxGridDBColumn

DataBinding.FieldName = State

end

object cxGrid1DBTableView1Country: TcxGridDBColumn

DataBinding.FieldName = Country

end

end

object cxGrid1Level1: TcxGridLevel

GridView = cxGrid1DBTableView1

end

end

cyblueboy83 發表於 2005-12-9 11:30:45

學習

hanlin2004 發表於 2005-12-9 13:14:52

我一般是這樣取cxGrid選中的紀錄的值的:

function TFrameAccount.GetSelectedID:variant;

var

AccID: array of string;

i, n: Integer;

Index: Integer;

begin

n := cxGrid1DBTableView1.DataController.GetSelectedCount;

for i:=0 to n – 1 do

begin

Index := cxGrid1DBTableView1.DataController.GetSelectedRowIndex(i);

setlength(AccID, length(AccID) + 1);

AccID[High(AccID)] :=cxGrid1DBTableView1.DataController.GetRowValue(cxGrid1DBTableView1.DataController.GetRowInfo(Index),0); //這裏的0是Grid中列的索引,0表示第一個列綁定的欄位

end;

result := AccID;

end;

DevExpress cxGrid的應用

在cxGrid下建立view,取名myView

1. 允許選擇多條記錄(MultiSelect):

   myView–OptionsSelection–MultiSelect 設成true

2. 取得選定行的值:

   myView->DataController->FocusedRowIndex 獲得選擇行的行號

   myView->DataController->Values[myView->DataController->FocusedRowIndex+1][0] 選擇的行的第一列的值

   myView->DataController->GetSelectedCount() 選擇多行的行數

   myView->DataController->GetSelectedRowIndex(行號n) 所選多行裏的第n行

3. VerticalGrid的單元值

控制項->Properties->Value 獲得單元的值,此值為variant類型,需要強制轉換成AnsiString

4. VerticalGrid裏的CheckGroup的使用

得到的值為: (;1,3,8)此為選擇了選項裏的第1、3、8項

5. VerticalGrid裏驗證

   TcxEditorRow的properties->EditorProperties選MaskEdit,然後再選下面的MaskEdit和MaskKind,可以限定輸入的東西

6. TcxPopupEdit控制項的應用,Form1加一個控制項cxPopupEdit1

屬性裏PopupControl指向你要彈出的表單Form2,Form2裏添加一個按鈕,說明文件裏添加

[Copy to clipboard] [ – ]

CODE:

private:        // User declarations

        AnsiString FEditValue;

        TcxPopupEdit *FPopupEdit;

。。。

public:

        __property AnsiString EditValue = {read=FEditValue,write=FEditValue};

        __property TcxPopupEdit *PopupEdit = {read=FPopupEdit, write=FPopupEdit};

在Form1的cxPopupEdit1控制項的事件裏添加下面的代碼

[Copy to clipboard] [ – ]

CODE:

//—————————————————————————

void __fastcall TForm1::cxPopupEdit1PropertiesInitPopup(TObject *Sender)

{

        Form2->PopupEdit = (TcxPopupEdit*)Sender;

}

//—————————————————————————

void __fastcall TForm1::cxPopupEdit1PropertiesCloseUp(TObject *Sender)

{

        cxPopupEdit1->EditValue = Form2->EditValue;

}

在Form1的按鈕事件裏可以加入

[Copy to clipboard] [ – ]

CODE:

        FEditValue = "嘻嘻哈哈";

        FAccepted = AAccepted;

        FPopupEdit->DroppedDown = false; 

//—————————————————————————

7. TcxGrid控制項去掉上面的"Drag a column header here to group by that column"欄

在控制項的view的OptionsView屬性裏有一個GroupByBox,設為false即可

呵呵,寫的有些亂,自己試著做吧

選擇了若干條記錄(MultiSelect)

選擇了若干條記錄(MultiSelect),現在要把這些選中的記錄從該資料庫複製到另一庫中,該如何做?

可以參考。我的程式是列印選擇的記錄 ,

你可以保存到其他表就好。

var i:integer;

begin

  if cxview1.DataController.Controller.SelectedRecordCount>0 then

    with cxview1.DataController.DataSource.DataSet do

    begin

      global.BQ_ppp(”,3); //只進行資料清除

      for i:=0 to cxview1.DataController.Controller.SelectedRecordCount-1 do

      begin

        GotoBookmark(Pointer(cxview1.DataController.GetSelectedBookmark(i)));

        if Pos(‘計’,fields[0].AsString)=0 then

        begin

          if CheckBox2.Checked then

            global.BQ_ppp(fields[0].AsString,0)//立即進行標籤列印,不把資料加到臨時資料庫。

          else

            global.BQ_ppp(fields[0].AsString,1); //加入資料到臨時資料庫。

        end;

      end;

      if CheckBox2.Checked=false then //列印中的資料只是包含一種標籤。 不是多種標籤列印,集中列印臨時資料庫中的資料。

        global.BQ_ppp(”,2); //只進行標籤列印

      Log_save(‘標籤補打’,’標籤列印’);

    end;

end;

來自:lihoulong, 時間:2006-7-8 23:59:31, ID:3500034

function CopyRecord(var recData: TArrayVariant): boolean;

var

  i: integer;

begin

  with FDataset do

  begin

    SetLength(recData, Fields.Count);

    for i := 0 to Fields.Count – 1 do

      recData[i] := Fields[i].Value;

  end;

  Result := true;

end;

function TwpQDTable.PasteRecord(

  const RecData: array of Variant): boolean;

var

  fcnt,

    i: integer;

begin

  with FDataset do

  try

    fcnt :=  Length(RecData) – 1;

    for i := 0 to fcnt do

    begin

      if FDataset.State in [dsBrowse] then

        Edit;

      Fields[i].Value := RecData[i];

    end;

    Result := true;

  except

    Result := false;

  end;

end;

定義一個記錄陣列

for i := 0 to cxgrid.SelectedCount-1 do  begin

依據關鍵字定位資料集,再執行CopyRecord

end;

在粘貼的地方用pasteRecord

cxGrid的使用方法

1.  去掉cxgrid中台頭的box ,在tableview1的ptionsview的groupbybox=false;

2.  在GRID footer 中加入sum(列), tableview1的optionsviewàfooter=ture

然後在cxGRid1的customize..中的summary 的footer.add需要合計的列kind= skSum

3.  去掉cxgrid 中的過濾下拉箭頭 選擇tableview1.optionscustomize.columnfiltering=fasle;

4.   cxGrid1DBTableView1 的 OptionView中屬性GroupFooters設為gfAlwaysVisible並設置需要求和的列,在summary.default for Groups 下add加入需要合計的欄位,column下顯示fieldname 為統計欄位,format為格式,kind為統計方法,position 為位子 spfooter 在分組的下面,spgroup 在分組的上面

或用cxGridPopupMenu1,在運行時可對任意數字類型列求和,方法是只需設置cxGridPopupMenu1的屬性Grid為cxGrid1DBTableView1的cxGrid,

即可實現您所需功能

5.  DEV Express裏的cxGrid默認的數值格式帶¥,怎么去掉啊!

6.  雙擊Cxgrid,選擇colmnum改變類型 options.properties.Memo

7.  在displayformat中進行設置

來源於大富翁論壇

使用cxGrid有一些時間了,在這裏總結一下使用cxGrid的一些方法,希望給剛開始接觸cxGrid的人一些幫助。

1.簡單介紹:cxGrid右下方的cxGrid1Level1是表示Grid表的層,cxGrid可以有多層,這相當於集合了PageControl的

功能,而cxGrid1Level1右邊的cxGrid1DBTableView1相當於DBGrid一樣。右擊cxGrid1可以添加cxGrid1Level2,右擊

cxGrid1Level2,可以選擇Create View , Add level 或者Delete Level。Add level可以增加子Level,Create View

裏面可以選擇很多不同總類的View。其中

  1)DB Table可以和資料庫連接的View,更一般的DBGrid類似,它比DBGrid多了比如滑鼠中鍵可以用,可以統計,

查詢,等等功能;

  2)DB Banded Table 則可以實現比如:

                    ———————————

                    |     說明1     |     說明2     |

                    ———————————

                    | 欄位1 | 欄位2 | 欄位3 | 欄位4 |

等類似的功能;

  3)DB Card View 則提供了卡片方式的顯示資料的功能,這個用在比如人事檔案管理比較不錯;

  4)其他不一一贅述。

2.一些使用方法:

  1)有圖片和MEMO的例子:

拖入一個cxGrid1,Table1,DataSource1。 Table1的DatabaseName設為DBDEMOS,TableName設為biolife.db,

   Active設為True;DataSource1的DataSet設為Table1;cxGrid1DBTableView1的DataController中的DataSource 

設為DataSource1;右擊cxGrid1DBTableView1選擇Create All Columns;雙擊cxGrid1,在彈出的窗口中找到

  cxGrid1DBTableView1Notes和cxGrid1DBTableView1Graphic,將它們的Properties屬性設為BlobEdit;運行看看

結果。再將cxGrid1DBTableView1Graphic的Properties屬性設為Image,再將Properties下的Stretch設為True,

將cxGrid1DBTableView1->optionsview->CellAutoHeight 設為True,看看結果。

  2)如何讓“Drag a column here to group by that column”不顯示

解決:點擊cxGrid1上的cxGrid1DBTableView1

在cxGrid1DBTableView1->optionsview->groupbybox:=false即可

注:OptionsView裏面有很多屬性可能經常要用,比如:ColumnAutoWith,Navigator等等,慢慢琢磨吧:)

  3)GroupPanel上面的英文[Drag a column header to group by that column]怎么可以改成中文?

解決:最簡單的方法是 TcxGridTableView.OnCustomDrawPartBackground ,也可用 OnCustomDrawGroupCell:

    procedure TForm1.cxGrid1DBTableView1CustomDrawPartBackground(

               Sender: TcxGridTableView; ACanvas: TcxCanvas;

              AViewInfo: TcxCustomGridCellViewInfo; var ADone: Boolean);

    begin

      AViewInfo.Text:=’動態設置 GroupBox 的顯示內容’;

      ACanvas.FillRect(AViewInfo.Bounds);

    end;

  4)如何實現如下功能:

           +財務部

           +原材料倉庫

           +成品庫

           +衝壓車間

           +軟體發展部

這個是部門的名稱,點擊加號就可以將本部門的人員情況顯示出來。

解決:其實這是一個主從表關係,1:填好主表的keyfieldnames

                                  2:填好從表的keyfieldnames

                                  3:填好從表的 detaikeyfieldNames與masterkeyfieldnames

                                  4: 從表的資料源一定要按與主表關聯的欄位排序

注:其他地方設置了主從表結構那樣就顯示不出來,比如設置了從表的Table或者Query的mastersource和

   asterfield就會不能顯示資料!如果是兩個cxGrid的主從關係,這樣設置就很OK了。

5)統計功能

解決:cxGrid1DBTableView1->optionsview->Footer 設為True

         cxGrid1DBTableView1->DataController->Summary設置FooterSummaryItems即可

6)類似PageControl顯示

解決:增加一個Level,將cxGrid1->RootLevelOptions->DetailTabsPosition設為dtpTop,然後相應的設置cxGrid1Level1,和cxGrid1Level2的Caption值。

未完待續。。。。。。。。。

7)如何設定左邊幾列,不能滾動?

解決:使用DB Banded Table才可以實現,

在cxGrid1DBBandedTableView裏建立Band0,Band1

         Band0的Fixed=tfLeft

         Band1的Fixed=tfnone

設置要鎖定的欄位的BandIndex=0,其他為1,就OK了。

8)怎樣實現如EXCEL一樣的,當前格=G14+G15+G16 這樣的功能

解決:舉一個簡單的例子:label1.Caption := cxGrid1DBTableView1.DataController.Values[2,

3]+cxGrid1DBTableView2.DataController.Values[1, 1]+cxGrid1DBTableView3.DataController.Values[1, 1];

所以不同cxGrid1DBTableView中的資料都可以給當前格,這樣就做到了EXCEL中的當前格=G14+G15+G16 類似的功能。

9)滑鼠右擊cxGrid1DBBandedTableView1功能表裏的Edit Layout什么用,怎么使用?

解決:可以拖動欄位,並列的可以拖成有層次感(一層層), 拖動時會顯示箭頭的,就是說可以拖一個欄位放

到最上面,就可以使記錄按此欄位進行分組。點擊其中一個欄位,上面還會出現一個上升或者下降的小三角形,這個

小三角形的作用是在運行階段,資料就會按照這個欄位上升或者下降排序。

還有一個Set as Default的作用是保持當前TableView的參數,下此產生新的TableView的時候就會可以和上次保持的參數一樣。這個還沒有做過試驗。

10)怎樣將cxGrid裏的數據導入到EXCEL,HTML,XML和TEXT

解決:這個問題在用了cxGrid以後變得異常簡單,

uses

cxExportGrid4Link;

procedure TForm1.Button1Click(Sender: TObject);

begin

ExportGrid4ToEXCEL(‘d:\wang.xsl’,cxGrid1,True,True);

ExportGrid4ToTEXT(‘d:\wang.txt’,cxGrid1,True,True);

ExportGrid4ToXML(‘d:\wang.xml’,cxGrid1,True,True);

ExportGrid4ToHTML(‘d:\wang.html’,cxGrid1,True,True);

end;

11)如何使滿足條件的資料顯示不同的顏色?

解決:

var

AYellowStyle: TcxStyle;

procedure TForm1.FormCreate(Sender: TObject);

begin

//行顏色

AYellowStyle := TcxStyle.Create(Self);

AYellowStyle.Color := $0080FFFF;

AYellowStyle.TextColor := clMaroon;

end;

procedure TForm1.cxGrid1DBBandedTableView1StylesGetContentStyle(

Sender: TcxCustomGridTableView; ARecord: TcxCustomGridRecord;

AItem: TcxCustomGridTableItem; out AStyle: TcxStyle);

begin

if ARecord.Values[cxGrid1DBBandedTableView1Lengthcm.Index] < 81 then

  AStyle := AYellowStyle;

end;

這裏cxGrid1DBBandedTableView1Lengthcm.Index小於81時就顯示黃色

12)如何從外邊的TXT文件導入到cxGrid?

解決:    procedure CustomizeColumns;

          procedure LoadData;

procedure TForm1.CustomizeColumns;

const

cDistance = 1;

cRadius = 5;

cPeriod = 4;

cPstring = 0;

var

I: Integer;

begin

DecimalSeparator := ‘.’;

with cxGrid1TableView2 do

for I := 0 to ColumnCount – 1 do

   if I in [cDistance, cRadius] then

     Columns[I].DataBinding.ValueTypeClass := TcxIntegerValueType//1,5列為Integer

   else

     if I in [cPstring,cPeriod] then

     Columns[I].DataBinding.ValueTypeClass := TcxStringValueType//0,4列為String

     else

      Columns[I].DataBinding.ValueTypeClass := TcxFloatValueType;//其他為Float

end;

procedure TForm1.LoadData;

const

AFileName = ‘資產負債表.txt’;

AHeaderLineCount = 2;

var

ARecords, AValues: TStringList;

I: Integer;

procedure InitRecord(const Str: string);

var

   J: Integer;

   V: Variant;

begin

   AValues.CommaText := Str;

   for J := 0 to AValues.Count – 1 do

    if AValues.Strings[J] <> ‘-‘ then

    begin

     V := AValues.Strings[J];

     if not VarIsNull(V) then

       cxGrid1TableView2.DataController.Values[I, J] := V;

    end;

end;

begin

if not FileExists(AFileName) then

   raise Exception.Create(‘Data file not found’);

ARecords := TStringList.Create;

AValues := TStringList.Create;

with ARecords do

try

   LoadFromFile(AFileName);

   cxGrid1TableView2.BeginUpdate;

   cxGrid1TableView2.DataController.RecordCount := Count – AHeaderLineCount;

   for I := 0 to Count – (AHeaderLineCount + 1) do

     InitRecord(Strings[I + AHeaderLineCount]);

finally

   cxGrid1TableView2.EndUpdate;

   ARecords.Free;

   AValues.Free;

end;

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

CustomizeColumns;

LoadData_Zcfz;

end;

13)如何改變列的顏色?

var

AFirstColumnStyle: TcxStyle;

procedure TForm1.FormCreate(Sender: TObject);

begin

//列顏色

AFirstColumnStyle := TcxStyle.Create(Self);

AFirstColumnStyle.Color := clAqua;

AFirstColumnStyle.TextColor := clBlue;

cxGrid1TableView1.Columns[1].Styles.Content := AFirstColumnStyle;

end;

14)Set as default的用法?

解決:Set as default的用法是為了解決設置參數的方便而做的,比如:

連好資料庫以後,更改cxGrid1DBBandedTableView1->OptionsCustomize->ColumnFiltering 設為False。(這個設置可以將欄位名的下拉單給去掉)更改cxGrid1DBBandedTableView1->OptionsView->Navigator 設置為True。然後右擊cxGrid1DBBandedTableView1,在彈出的菜單欄裏麵點擊Set as default。

  OK,下次你再產生一個新的cxGrid1DBBandedTableView1時這些設置和剛才的一樣了。如果需要設置的參數很多的時候,這個Set as default很有用!

15)怎樣使滑鼠移動時,相應的單元裏的文字變色?

解決:

var

FTrackItem: TcxCustomGridTableItem;

FTrackRec: TcxCustomGridRecord;

procedure TForm1.cxGrid1DBTableView1CustomDrawCell(

Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;

AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);

begin

if (AViewInfo.GridRecord = FTrackRec) and (AViewInfo.Item = FTrackItem) then

begin

   ACanvas.Font.Color := clred;   //紅色字體

   ACanvas.Font.Style := [fsUnderline];//帶下劃線

end;

end;

procedure TForm1.cxGrid1DBTableView1MouseMove(Sender: TObject;

Shift: TShiftState; X, Y: Integer);

var

AHitTest: TcxCustomGridHitTest;

ATrackItem: TcxCustomGridTableItem;

ATrackRec: TcxCustomGridRecord;

begin

ATrackItem := FTrackItem;

ATrackRec := FTrackRec;

AHitTest := (Sender as TcxGridSite).GridView.ViewInfo.GetHitTest(X, Y);

if AHitTest is TcxGridRecordCellHitTest then

begin

   FTrackItem := TcxGridRecordCellHitTest(AHitTest).Item;

   FTrackRec := TcxGridRecordCellHitTest(AHitTest).GridRecord;

end

else

begin

   FTrackItem := nil;

   FTrackRec := nil;

end;

if (ATrackItem <> FTrackItem) or (ATrackRec <> FTrackRec) then

begin

   // Invalidate old cell

   if ATrackRec <> nil then

     ATrackRec.Invalidate(ATrackItem);

   // Invalidate new cell

   if FTrackRec <> nil then

     FTrackRec.Invalidate(FTrackItem);

end;

end;

16)ExpressQuantumGrid 3.2.2中的dxdbgrid和4.2版本中的cxgrid有什么區別?

有很大的區別,基本上相當於是兩個控制項一樣。

cxgrid是在dxdbgrid基礎上完全重寫的,所以cxgrid不支持dxdbgrid

所以cxgrid裏面特意提供了一個將dxdbgrid導入到cxgrid的功能。

17)怎樣設計多表頭的cxGrid?

解決:cxGrid可以解決如下的表頭:

                   ———————————

                   |     說明1     |     說明2     |

                   ———————————

                   | 欄位1 | 欄位2 | 欄位3 | 欄位4 |

                   |      欄位5    |     欄位6     |

                   |      欄位7    | 欄位8 | 欄位9 |

實現這個很簡單,你可以直接在上面拖動欄位名,拖動時會顯示箭頭的,放入你想顯示的位置就OK了。或者在滑鼠右擊cxGrid1DBBandedTableView1功能表裏的Edit Layout裏也可以拖放。

但是cxGrid不能實現如下的多表頭形式:

                   ———————————

                   |     說明1     |     說明2     |

                   ———————————

                   | 說明3 | 說明4 | 說明5 | 說明6 |

                   |      欄位1    |     欄位2     |

                   |      欄位3    | 欄位4 | 欄位5 |

不知道有誰能實現這樣的多表頭?

18)在主從表結構時,當點開“+”時怎樣將焦點聚在相應主表的記錄上?

解決:

var

HitTest: TcxCustomGridHitTest;

procedure TColumnsShareDemoMainForm.tvProjectsMouseDown(Sender: TObject;

Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

// Note that the Sender parameter is a Site

HitTest := (Sender as TcxGridSite).GridView.ViewInfo.GetHitTest(X, Y);

// The point belongs to the [+]/[-] button area

if HitTest is TcxGridExpandButtonHitTest then

   // Move focus to the record

   TcxGridExpandButtonHitTest(HitTest).GridRecord.Focused := True;

end;

19)CXGrid4如何展開全部節點

解決:GridDBTableView1.DataController.Groups.FullExpand;

2003-12-12 17:07:30    問題20

20)cxGrid如何動態創建Items的Editor的項?

   cxGrid的列有一個屬性,它的編輯框可以指定combobox,spinedit等.在設計時,可以為

   combobox的items添加項目.請問是否可以動態創建?(run-time時由程式加入)

解決:

var

  A:TDataSource:

  B:TcxlookupcomboboxProperties;

      begin

  A:=TDataSource.create(self);

  B:=tcxlookupcomboboxproperties.create(self);

  A.Dataset:=Dic_ry_xb;//此處指定數據源。

  b.listdource:=a;//此處指明欄位的listsource屬性。

  b.keyfieldnames:=’a’;    //此處指明欄位的關鍵字段

  b.listfieldnames:=’b’;   //此處指明欄位的返回值。

  b.listcolumns.items[0].caption:=’x;  //此處默認是會建立一個欄位,但是顯示的表頭是name,所以此處讓它顯示為自己想要的中午顯示。

        cxGrid1DBTableView1c1_sex_code.Properties:=b;  //此處指明是那個欄位。

end;  //這個是初始化的代碼,

2004-1-7 14:05:14    問題21

21)ExpressQuantumGrid4.5的漢化包

在這裏可以下載ExpressQuantumGrid4.5的漢化包,將檔直接覆蓋到原始檔案就可以了。

如何在dxMemData1或cxGrid1中動態添加欄位?

Procedure TcxGridDBTableView.CreateDefaultColumn;      //建立默認的列  //Add By Pgt

Var

  CxColumn:TcxGridDBColumn;

  FootItem:TcxDataSummaryItem;

  i:Integer;

  OldAutoWidth:Boolean;

Begin

  If Assigned(DataController.DataSource) And

     Assigned(DataController.DataSource.DataSet) And

     DataController.DataSource.DataSet.Active Then Begin

     With DataController.DataSource.DataSet Do Begin

       While ColumnCount>0 Do

         Columns[0].Free ;

       For i:=0 to FieldCount -1 Do Begin

         If (Fields[i].DataType<>ftAutoInc) And (UpperCase(Fields[i].FullName)<>’ID’) Then Begin

           CxColumn:=Self.CreateColumn ;

           CxColumn.DataBinding.FieldName := Fields[i].FullName ;

           CxColumn.HeaderAlignmentHorz := taCenter ;

           CxColumn.HeaderAlignmentVert := VaCenter ;

           If CxColumn.Width >150 Then CxColumn.Width := 150 ;

           If i=0 Then Begin

             FootItem := DataController.Summary.FooterSummaryItems.Add ;

             FootItem.ItemLink :=CxColumn ;

             FootItem.Format := ‘共0條’;

             FootItem.Kind := skCount ;

           End Else Begin

             If (Fields[i].DataType = ftFloat) And (Pos(‘價’,Fields[i].FullName)=0) Then Begin

               FootItem := DataController.Summary.FooterSummaryItems.Add ;

               FootItem.ItemLink :=CxColumn ;

               If Pos(‘數量’,Fields[i].FullName)<>0 Then

                 FootItem.Format := ‘,0;-,0’

               Else Begin

                 FootItem.Format := ‘,0.00;-,0.00’ ; // ‘¥,0.00;-¥,0.00’;

                 If CxColumn.Width<80 Then CxColumn.Width := 80 ;

               End;

               FootItem.DisplayName := Fields[i].FullName ;

               FootItem.Kind := skSum ;

             End;

           End;

         End;

       End;

       OldAutoWidth := Self.OptionsView.ColumnAutoWidth ;

       Self.OptionsView.ColumnAutoWidth := True ;

       Self.OptionsView.ColumnAutoWidth := OldAutoWidth ;

     End;

  End;

End;

利用 procmail 的過濾信件(Postfix )

利用 procmail 的過濾信件(Postfix )

參考網址:http://blog.weithenn.org/2009/06/freebsdpostfix-amavisd-new-uvscan.html

Procmail 部份 (自訂郵件收送規則)

步驟1.安裝 Procmail 套件

切換至 Ports Tree 路徑安裝 Procmail 套件(請尊重 weithenn 的辛勞!!)

#cd /usr/ports/mail/procmail //切換至安裝路徑
#make install clean //安裝套件並清除安裝過程中不必要的檔案

步驟2.修改 Postfix 設定檔 (main.cf)

修改 Postfix 設定檔 main.cf 內容如下

#vi /usr/local/etc/postfix/main.cf //修改 Postfix 設定檔
mailbox_command = /usr/local/bin/procmail //加入此行 (自訂的規則會套用至所有帳號)

步驟3.編寫過濾規則 (procmailrc)

編寫過濾規則設定檔 Promailrc 下列過濾規則為收集網路上資料而成的範例。(請尊重 weithenn 的辛勞!!)

  • 所有使用者的過濾條件: /usr/loca/etc/procmailrc
  • 個別使用者的過濾條件: .procmailrc (使用者家目錄下透過 .forware 來啟動 procmail)

使用者可透過在個人家目錄下 .forward 加入如下內容來達到自訂個人過濾條件的目的 (請依個人喜好擇一即可)

#cat ~/.forward
"| /usr/local/bin/procmail" //加入此行 (方式一)
"|IFS=' ' && exec /usr/local/bin/procmail -f- || exit 75 $USER" //加入此行 (方式二)

以下為自訂所有使用者的過濾條件,其中的 /dev/null 可以換成別的目錄 (ex./var/virusmails)。內容如下 (當然您可依個人需求新增/刪除)

#vi /usr/loca/etc/procmailrc
VERBOSE=off
LOGFILE=/var/log/procmail.log
###########################################################################
###Procmail 寄進來的郵件依下列規則逐一過濾,未符合底下規則的信件都放行 ###
###Subjcet 主旨 ###
###Content-Type: ###
###########################################################################
############ KLEZ.G Virus ############
:0b
* ^Subject:.*(Let's be friends)
/dev/null
###
:0b
* ^Subject:.*A funny game
/dev/null
###
:0b
* ^Subject:.*Hello\,.*\,how are you.*
/dev/null
###
:0 B
* ^Content-Type:.*audio/x-wav.*
* ^.*name=.*\.(scr|SCR)
/dev/null
###
:0 B
* ^Content-Type:.*audio/x-midi.*
* ^.*name=.*\.(scr|SCR)
/dev/null
###
:0 B
* ^Content-Type:.*application/octet-stream.*
* ^.*name=.*\.(scr|SCR)
/dev/null
###
:0 Bb
* ^This game is my first work.*
* ^You\'re the first player.*
* I.*you would .* it.*
/dev/null
###
:0 Bb
* .*This is a.*patch.*
* ^I .* you would.*it.*
/dev/null
###
:0 Bb
* .*iframe src=3Dcid.*height=3D0 width=3D0.*
/dev/null
###
:0 B
* ^Content-Type:.*multipart/mixed.*
* name="ANTI_CIH.EXE"
/dev/null
###
:0b
* ^Subject:.*W32.Klez.*removal tools.*
/dev/null
############## Nimda Virus ###############
:0 Bh
* ^Content-Type:.*audio/x-wav.*
* name="readme.exe"
/dev/null
###
:0 Bh
* ^Content-Type:.*audio/x-wav.*
* name="sample.exe"
/dev/null
###
:0 B
* ^Content-Type:.*multipart/mixed.*
* name="readme.exe"
/dev/null
###
:0 B
* ^Content-Type:.*multipart/mixed.*
* name="sample.exe"
/dev/null
###
:0 B
* ^Content-Type:.*application.*
* name="readme.exe"
/dev/null
###
:0 B
* ^Content-Type:.*application.*
* name="sample.exe"
/dev/null
############# SirCam Virus ############
:0 Bh
* I send you this file in order to have your advice
/dev/null
############# PE.BRID.A ############
:0 H
* ^X-Mailer: EBT Reporter.*$
/dev/null
###
:0 B
* ^.*[Nn][Aa][Mm][Ee]=README\.EXE.*$
/dev/null
#############廣告信 (下列三種挑一個吧) ##############
:0:
* ^X-Spam-Flag:.*YES
/dev/null
:0:
* ^X-Spam-Level:.\*\*\*\*\*
/dev/null
:0:
* ^X-Spam-Status:.*Yes
/dev/null

建立 Procmail Log 以便後續觀察 Procmail 運作狀況,若要允許使用者的 Procmail 過濾規則也可寫入該 Log 的話則權限請設定為 666(請尊重 weithenn 的辛勞!!)

#touch /var/log/procmail.log //建立 Procmail Log
#chmod 666 /var/log/procmail.log //允許使用者的 Procmail 過濾規則也可寫入

步驟4.測試過濾規則

在測試過程中可以針對 A funny game 主旨來進行測試並且把 /dev/null 改成/var/virusmails。寄此主旨的信件給使用者然後使用 mailstat 來觀察。

#mailstat -km /var/log/procmail.log

步驟5.如何過濾中文廣告信

由於中文編碼 (中文廣告信) 進入系統後會顯示為亂碼,因此若是您直接在過濾規則內打中文是無法過濾中文廣告信的,所以請安裝 mmencode 套件,將中文字轉換為 MIME Code。

#cd /usr/ports/converters/mmencode //切換到安裝路徑
#make install clean //安裝並清除過程中不必要的檔案

MIME 定義兩種編碼方法:Base64 與 QP(Quote-Printable) 而含有 MIME 編碼的郵件若您查看它的源始碼會含有 "This is a multi-part message in MIME format." 這樣的句子。

  • Base64: 預設值,將整個檔案資料重新編碼為 7bits
    • 以下將中文字 打炮 轉換成 MIME 編碼中的 Base64 以及將 Base64 轉換回中文

#echo "打炮" | mmencode //中文轉換為 Base64
pbSstgo=
#echo "pbSstgo=" |mmencode -u //Base64 轉換為中文
打炮

  • QP (Quote-Printable): 將 8bits 中文資料轉換為 7bits
    • 以下將中文字 打炮 轉換成 MIME 編碼中的 QP 以及將 QP 轉換回中文

#echo "打炮" | mmencode -q //中文轉換為 QP
=A5=B4=AC=B6
#echo "=A5=B4=AC=B6" | mmencode -q -u //QP 轉換為中文
打炮

在 Procemail 過濾規則 (procmailrc) 中可以接受 Base64 及 QP 的 MIME 編碼,以下過濾規則中為郵件主旨中只要有打炮這二個中文字眼就把該 Mail 移到 /dev/null 去。

:0b
* ^Subject:.*(pbSstgo=)* //Base64 Code
/dev/null
:0b
* ^Subject:.*(=A5=B4=AC=B6)* //QP Code
/dev/null

POSTFIX針對特定垃圾信主旨過濾

最近公司同仁收到很多DHL的病毒信,叫收信的人要開附件zip檔案,內附的文件是 *.exe,叫我家的狗想,他都知道 200% 是病毒,但是還是怕有同仁”誤點”,還是在SERVER上先阻擋吧,發現主旨不會變,找到了下面方式來擋特定主旨
參考網址:http://ak6783.blogspot.com/2009/06/blog-post_11.html
POSTFIX 針對特定垃圾信主旨過濾

小弟公司的MailServer是用Postfix+MailScanner+Spamassassin
因為為了"方便"公司同事,所有垃圾信都是直接轉到某個信箱,而誤判的正常信再由我們轉給同事,原來我們IT也算是另類的郵差啊^_^
最近整理垃圾信的時候發現,那些寄藥品廣告的(大家應該知道是哪家吧)的主旨都好固定哦,這讓我愛死他們了,因為固定那我幾乎可以直接把它們給過濾掉
在/etc/postfix/header_checks裡
我增加了

/^Subject:.*You’ve received a greeting ecard/ DISCARD
/^Subject:.*Pharmacy Discount ID*/ DISCARD
/^Subject:.RE: DISCOUNT ID*/ DISCARD

我重新啟動了MailScanner後,以後這個主旨垃圾信就連進來都不會進來了
那你說,垃圾信可以換一個主旨再來啊,沒錯啊,就好像防毒軟體常常要更新一樣啊,它可以變啊,我也可以增加啊,反正我已經有防垃圾信的機制,再配合手動增加這種幾乎是一模一樣的主旨來過濾,幾乎九成九都可以過濾
記住,沒有一個防毒或是防垃圾信的軟體是全自動且百分之百,認真的管理才是最重要的^_^

ESXi 下的VM硬碟壓縮釋放空間問題

ESXi 下的VM硬碟壓縮釋放空間問題

文章出處 : http://hector958.pixnet.net/blog/post/26399389

==================================================

20110217補充:

關於VMWARE的thin provisioning,繼某SERVER使用CONVERTER匯出方式解決,另外有這台SERVER配置30GB硬碟,系統中剩餘5GB,但是VMDK一直是佔滿30GB/30GB的異常狀態。

同樣的搞了很久無解,當使用以下方法標記非使用中的BLOCK為0後,SVMOTION無效、CLONE去另個STORAGE無效、只有匯出有效。所以確認一件事就是:

VM的CLONE是BLOCK TO BLOCK的搬動;匯出則是建立VMDK後FILE TO FILE的搬動,而BLOCK標記為0的部分沒有被SVMOTION與CLONE的動作影響。

研究之後發現是VMWARE的BUG,當在作SVMOTION的時候,來源與目標磁區的BLOCK SIZE相同的話,會導致BLOCK被標記為0處無法清除,所以必須SVMOTION去一個不同BLOCK SIZE的STORAGE才行。

例如把VDisk00_V1上的東西(BLOCK SIZE=8MB)搬去VDISK01_V4(BLOCK SIZE=8MB),thin provisioning無效。

但VDisk00_V1上的東西(BLOCK SIZE=8MB)搬去ESXi2_ihd(BLOCK SIZE=1MB) ,thin provisioning生效。


當我們使用虛擬機器時,虛擬硬碟的形式可以選thin provisioning,但是明明配置的空間中只用了一半,為何管理上看起來卻大小明顯超過?VMDK的大小也明顯超過?

像這樣 :WINDOS中明明只有用一半:

000

但是去觀察虛擬環境中去吃的滿滿的:

001.jpg

這明顯有問題,其實是因為WINDOWS的檔案殺了不是真殺,這大家應該都知道。

在WINDOWS之中原本硬碟塞了資料,而後來砍掉之後卻沒有把空間釋放,vmdk大小沒有縮回來,這一點VMWARE就沒有辦法幫我們處理了。

處理的辦法:

首先有空的話最好是WINDOWS硬碟先重組,然後要用SDELETE這個工具程式,去微軟下載這個47K的小程式:

http://www.microsoft.com/taiwan/technet/sysinternals/FileAndDisk/SDelete.mspx

上面連結似乎沒了,請下載微軟瑞士刀工具:
http://technet.microsoft.com/en-us/sysinternals/bb842062.aspx

然後複製去虛擬機器的硬碟下,用命令列執行:

sdelete -c c:

這樣會把 c 槽的空白地方都標成0,等他跑完以後,用storage vmotion把這台vm的檔案搬去另一個storge空間,過程中選thin provisioning形式。

等搬完之後,硬碟所佔用空間的大小就縮回來了。

使用Office 2003 特殊功能將 PDF 轉成 WORD

網路上找的 http://blog.xuite.net/esther1013_2000/wenchi/7700354
=========================================================
在老爹的網站看到老爹寫的,應該很好用^^

使用Office 2003 特殊功能將 PDF 轉成 WORD

昨天,一位同事問我,有沒有辦法將PDF轉成Word檔?印象中,應該有辦法,於是上網找了找,找到幾個試用軟體,試了幾個,效果都不太理想。而且,由於PDF檔案可說是圖形檔案,要轉成Word檔案,基本上是以OCR(文字辨識)的原理進行,所以轉檔效果不是很理想。在網路上多找幾下,居然看到Word2003本身就有將PDF轉成Word的功能,跟著說明作了一遍,辨識效果依然不算十全十美,但比起重打,那好得太多了。就跟大家分享,這個Word2003的轉檔功能。

可以利用Office 2003中的Microsoft Office Document Imaging元件來實現PDF轉WORD文檔,也就是說利用WORD來完成該任務。方法如下:

用Adobe Reader打開想轉換的PDF檔,接下來選擇“檔案→列印”功能表,在打開的“列印”視窗中將“印表機”欄中的名稱設置為“Microsoft Office Document Image Writer”,確認後將該PDF檔輸出為MDI格式的虛擬列印檔。

如果沒有找到“Microsoft Office Document Image Writer”項,使用Office 2003安裝光碟中的“添加/刪除元件”更新安裝該元件,選中“Office 工具 Microsoft DRAW轉換器”。然後,運行“Microsoft Office Document Imaging”,並利用它來打開剛才保存的MDI檔,選擇“工具→將文本發送到Word”功能表,在彈出的視窗中選中“在輸出時保持圖片版式不變”,確認後系統會提示“必須在執行此操作前重新運行OCR。這可能需要一些時間”,不管它,確認即可。

對PDF轉DOC的識別率不是特別完美,轉換後會丟失原來的排版格式,所以轉換後還需要手工對其進行排版和校對工作。

以上僅在word2003中可用,其他版本沒有Microsoft Office Document Image Writer。

http://blog.xuite.net/mschiang/prayer/7698197/track

Windows 7 64Bit 繁體中文 Big5 執行中文程式中文選項字型變亂碼問題 asus預載系統常遇到

Windows 7 64Bit 繁體中文 Big5 執行中文程式中文選項字型變亂碼問題,我遇到的更詭異…………其中一人的網域帳號登入執行軟體都正常,使用其它帳號包含admin,執行軟體都變亂碼……………

修正出處:

http://www.nwself.com/2009/12/windows-7-bug-in-asus-nb-os.html

 

修正方式:

regedit 將機碼修改成下方數值後重開機應該就可解決了。

[HKEY_CURRENT_USER\Control Panel\International]
"Locale"="00000404"

vcbMounter 備份出現 Error Backup snapshot already exists

解決的方式很簡易,開啟VI Client後,到該台VM刪除底下的“_VCB-BACKUP_” 快照即可。

vcbMounter Error Backup snapshot already exists

http://networkadminkb.com/kb/Knowledge%20Base/VMWare/vcbMounter%20Error%20Backup%20snapshot%20already%20exists.aspx

You must manually delete the existing “_VCB-BACKUP_” snap-shot in VirtualCenter using the VI Client.

1) Open the VI Client

2) Right click the affected virtual machine

3) Select Snapshot…Snapshot Manager

4) Select _VCB-BACKUP_

5) Click Delete

6) Click Yes