데이터가 제법 많은 목록에서 제목을 LIKE 검색하는 경우,

혹은 공백을 포함한 문자열의 공백 제거 후 검색을 하는 경우,

속도 이슈가 발생한다. 


이런 경우 DBMS에서 제공하는 FullTextSearch 기능을 사용하면 훨씬 빠른 결과를 얻을 수 있다. 


그런데 Devexpress GridControl을 사용하는 경우.... 

AutoFilter에서 검색시 Filter 정보에는 

contains([검색필드명], N'검색어') 로 입력되며,


실제로 DBMS에서 실행되는 Query문을 확인해보면 

    (isnull(CharIndex(N'검색어', [검색필드명]), 0) > 0 


이런 식이다... 대략 낭패 OTL


어찌해야 AutoFilter에서  FullTextSearch를 사용할 수 있을까?


찾아보니 아래와 같이 ICustomFunctionOperatorFormattable 인터페이스를 구현한 클래스를 추가하면 가능하다는 것을 알았다.


< 구현 방법 >


1. ICustomFunctionOperatorFormattable 를 구현한 클래스를 생성한다.

이름 지정과 포멧 함수 구현이 핵심인 듯...

using System.Data;
using DevExpress.Xpo.DB;
using DevExpress.Data.Filtering;

public class FullTextContainsFunction : ICustomFunctionOperatorFormattable {
    #region ICustomFunctionOperator Members
    // Evaluates the function on the client 
    public object Evaluate(params object[] operands) {
        // Full text search is not available on the client and should not be used there 
        throw new NotImplementedException();
    }
    public string Name {
        get { return "FullTextContains"; }
    }
    public Type ResultType(params Type[] operands) {
        return typeof(bool);
    }
    #endregion
    #region ICustomFunctionOperatorFormattable Members
    // The function's expression to be evaluated on the server 
    public string Format(Type providerType, params string[] operands) {
        // This example implements the function for MS SQL databases only 
        if (providerType == typeof(MSSqlConnectionProvider))
            return string.Format("contains({0}, {1})", operands[0], operands[1]);
        throw new NotSupportedException(string.Concat("This provider is not supported: ", 
            providerType.Name));
    }
    #endregion
}


2. 프로그램 시작시 ICustomFunctionOperatorFormattable 를 구현한 클래스의 인스턴스를 CriteriaOperator에 커스텀 함수로 등록한다.


// program.cs 나 MainForm 에 추가한다.

CriteriaOperator.RegisterCustomFunction(new FullTextContainsFunction());



3. 그리고 필터에서 검색시 아래와 같이 필터를 입력한다.


CriteriaOperator.Parse("FullTextContains([필드명], '검색어')");




결과는 아주 잘 작동한다.


* 참고 : https://documentation.devexpress.com/CoreLibraries/3246/DevExpress-ORM-Tool/Examples/How-to-Implement-a-Full-Text-Search






엑셀 출력시.. 가장쉬운 방법이

Grid에 Data Binding 한 후 그대로 Export 하는 방법인데..


//

gridControl.ExportToXlsx(path);


했더니 .. 그리드 헤더 부분이 아래처럼 Grouping 되서 출력된다...


문제는 ExportType!


// Export 시, 아래처럼 옵션을 설정할 수 있다

XlsxExportOptionsEx xlsxOptions = new XlsxExportOptionsEx();
xlsxOptions.ShowGridLines = true;   // 라인출력 
xlsxOptions.SheetName = "test";    // sheet 명
xlsxOptions.ExportType = DevExpress.Export.ExportType.WYSIWYG;    // ExportType

gridControl.ExportToXlsx(exportFilePath, xlsxOptions);


WYSIWYG (위지윅)이란? what you see is what you get  (보이는 데로 얻는다. )

보이는 그데로 출력된다는 IT 용어.


 



이제야 내가 의도한데로 나옴.. 삽질 3시간함.


자세한 설명은 아래 링크 참조 ..

https://documentation.devexpress.com/#WindowsForms/CustomDocument17733



하나 더..

그리드에서 Export 할때 유용한 Method ..


http://stackoverflow.com/questions/14583067/devexpress-export-gridview-to-excel


// 위 Link에서 내용 발췌

private void mnuExportTable_ItemClick_1(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
    using (SaveFileDialog saveDialog = new SaveFileDialog())
    {
        saveDialog.Filter = "Excel (2003)(.xls)|*.xls|Excel (2010) (.xlsx)|*.xlsx |RichText File (.rtf)|*.rtf |Pdf File (.pdf)|*.pdf |Html File (.html)|*.html";
        if (saveDialog.ShowDialog() != DialogResult.Cancel)
        {
            string exportFilePath = saveDialog.FileName;
            string fileExtenstion = new FileInfo(exportFilePath).Extension;

            switch (fileExtenstion)
            {
                case ".xls":
                    gridControl.ExportToXls(exportFilePath);
                    break;
                case ".xlsx":
                    gridControl.ExportToXlsx(exportFilePath);
                    break;
                case ".rtf":
                    gridControl.ExportToRtf(exportFilePath);
                    break;
                case ".pdf":
                    gridControl.ExportToPdf(exportFilePath);
                    break;
                case ".html":
                    gridControl.ExportToHtml(exportFilePath);
                    break;
                case ".mht":
                    gridControl.ExportToMht(exportFilePath);
                    break;
                default:
                    break;
            }

            if (File.Exists(exportFilePath))
            {
               try
               {
                   //Try to open the file and let windows decide how to open it.
                   System.Diagnostics.Process.Start(exportFilePath);
                }
                catch
                {
                    String msg = "The file could not be opened." + Environment.NewLine + Environment.NewLine + "Path: " + exportFilePath;
                    MessageBox.Show(msg, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
             }
             else
             {
                 String msg = "The file could not be saved." + Environment.NewLine + Environment.NewLine + "Path: " + exportFilePath;
                 MessageBox.Show(msg, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
             }
        }
    }
}



MemoEdit 에 라인수를 제한하고 싶은경우


void memoEdit_EditValueChanging(object sender, DevExpress.XtraEditors.Controls.ChangingEventArgs e)
{
            string s = e.NewValue as string;
            int index = 0;
            int lineCount = 0;
            int startIndex = 0;


            while ((index = s.IndexOf( "\r\n" , startIndex)) >= 0)
            {
                startIndex = index + 2;
                lineCount++;
            }


            if (lineCount > 9)
            {
                XtraMessageBox.Show(this, "최대 10줄까지 입력가능합니다.", "입력제한알림", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                e.Cancel = true;
            }

        }



참고

http://www.devexpress.com/Support/Center/Question/Details/Q51262


한라인의 문자수를 제한하고 싶은경우 참고

http://www.devexpress.com/Support/Center/Question/Details/Q21297 


윈도우8.1 에서 데브 컨트롤 사용시 한글입력이 제대로 되지 않는 문제가 발생한다.


한글 입력이 완료 (엔터나 스페이스 또는 방향키 입력)되지 않은 상태에서

다른 컨트롤로 포커스를 이동하면 마지막 글자가 잘리거나 혹은 입력된 한글이 지워지는 문제가 발생한다.


이럴떄 해결 방법은 ....


subsystem version 을 수정해서 컴파일 하면 문제없이 동작한다.



방법 :

csproj/vbproj 파일 열어서


  <PropertyGroup>
    <SubsystemVersion>5.01</SubsystemVersion>
  </PropertyGroup>


 
태그를 추가해주고 컴파일하면 끝~!



자세한 내용은 아래 URL을 참고

http://www.devexpress.com/Support/Center/Question/Details/Q570706



+ Recent posts