NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    C# C# .NET 매크로 프로그램 만들기. (텍스트 파일 또는 엑셀 파일 반복 매크로 만들기 2부)

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 1부에 이어서 오늘은 포이치 반복(Foreach Repeat) 액션을 만들어 볼께요. 포 반복(For Repeat)은 사용자가 반복할 횟수를 설정하는 방식이지만, 포이치 반복은 텍스트 파일의 줄이나 엑셀의 셀 값들 또는 배열과 같은 자료형을 반복시키는 액션입니다. 우선, 코드를 먼저 작성해보고 테스트를 하면서 For 반복과 Foreach 반복이 어떤 차이가 있는지 확인하는게 이해하는데 빠를거 같네요.

     

    모델 라이브러리에 ForeachModel 클래스를 추가했습니다.

    9kdjlis.jpeg

     

     

    대부분의 로직 설명은 1부에서 For 반복을 만들면서 설명했기 때문에 여기에서는 더이상 반복 작업 처리 로직은 다루지 않고, 포이치 반복의 항목을 순회하면서 처리하는 방법만 알아볼께요. 우선, 포이치 반복은 데이타 소스가 있어야 합니다. 이 데이타 소스만큼 반복해야 하기 때문입니다.

    [NonSerialized]
    private List<string?>? _datas = null;
    
    [Browsable(false)]
    public List<string> Datas 
    { 
        get 
        {
            if (_datas == null)
                _datas = new List<string>();
    
            return _datas; 
        } 
    }

     

    Foreach 반복은 파일 또는 엑셀, CSV와 같은 문서 형태의 데이타도 사용할 수 있습니다. 따라서, 파일을 선택할 수 있는 속성이 하나 필요합니다.

    [LocalizedCategory("Action")]
    [LocalizedDisplayName("SelectDataSource")]
    [LocalizedDescription("SelectDataSource")]
    [Browsable(true)]
    [DefaultValue(null)]
    [Editor(typeof(TypeEditor.OpenFileSelectorEditor), typeof(UITypeEditor))]
    public string? SelectDataSource { get; set; }


    데이타 형식의 미스매치로 인해 에러가 발생하는 상황을 방지하기 위해 아래와 같이 데이타의 형식을 사용자가 선택하도록 합니다.

    [LocalizedCategory("Action")]
    [LocalizedDisplayName("DataSourceType")]
    [LocalizedDescription("DataSourceType")]
    [Browsable(true)]
    [DefaultValue(typeof(Definition.FileType), "Txt")]
    public Ai.Definition.FileType DataSourceType { get; set; } = Definition.FileType.Txt;

     

    현재 데이타 형식은 아래와 같습니다. 지금은 3가지만 처리할 수 있지만, 나중에는 어떤 파일이 더 추가될지는 모르겠습니다. 현재는 3개만 처리하도록 할께요.

    public enum FileType
    {
        Txt = 0,
        Excel = 1,
        Csv = 2
    }

     

    포이치에서 반복할 데이타를 가공해야 하는데요. 아래 메소드가 처리할 수 있도록 해줍니다. CSV 파일은 나중에 추가해야 할거 같아요.

    public int ForeachDataCount()
    {
        switch (DataSourceType)
        {
            case Definition.FileType.Txt:
                _datas = File.ReadAllLines(SelectDataSource).ToList();
                break;
            case Definition.FileType.Csv:
                break;
            case Definition.FileType.Excel:
                _datas = ExcelExt.Manager.Read(SelectDataSource, UseHeader, TableDirection, CustomColumns, SheetNames);
                break;
        }
    
        return _datas.Count;
    }

     

    닷넷에서 텍스트 파일을 처리하는 방법은 간단합니다. File.ReadAllLines와 같이 File 클래스의 ReadAllLines 스태틱 메소드를 사용하여 모든 라인의 텍스트를 배열로 가져올 수 있습니다. 아래와 같이 텍스트 파일을 하나 만들고, 내용을 한줄에 하나씩 입력 해보세요.

    2vzDtYn.jpeg

     

     

    매크로 엔진에서 For 반복 처리와 Foreach 반복 처리 로직을 분기해서 만들어야 합니다. 반복기라는 본연의 의무는 동일하지만, 처리 방식이 다르기 때문에 아래와 같이 자기 속성을 초기화 해줘야 합니다. 안그러면 내용이 남아 있어서 건너뛰기나 문제 발생시 이전 값이 활용될 수 있습니다. 만약, 이전 값이 남아서 다시 사용되면 원하지 않는 동작이 될수도 있으니 이 부분은 항상 유의해야 합니다.

    else if (action is Ai.Model.Action.Function.ForeachModel)
    {
        var foreachAction = (Ai.Model.Action.Function.ForeachModel)action;
        foreachAction.CurrentRepeatCount = 0;
        foreachAction.CurrentData = null;
        foreachAction.Datas.Clear();

     

    그리고, 엑셀을 처리하는 부분도 같이 알아볼께요. 텍스트 파일과는 다르게 엑셀은 몇가지 속성을 사용자가 선택할 수 있도록 해야 합니다.

    [LocalizedCategory("Excel")]
    [LocalizedDisplayName("UseHeader")]
    [LocalizedDescription("UseHeader")]
    [Browsable(true)]
    [DefaultValue(false)]
    public bool UseHeader { get; set; }
    
    [LocalizedCategory("Excel")]
    [LocalizedDisplayName("TableDirection")]
    [LocalizedDescription("TableDirection")]
    [Browsable(true)]
    [DefaultValue(typeof(Ai.Definition.TableDirection), "ColumnRow")]
    public Ai.Definition.TableDirection TableDirection { get; set; } = Definition.TableDirection.ColumnRow;
    
    [LocalizedCategory("Excel")]
    [LocalizedDisplayName("CustomColumns")]
    [LocalizedDescription("CustomColumns")]
    [Browsable(true)]
    [DefaultValue(null)]
    public string[]? CustomColumns { get; set; }
    
    [LocalizedCategory("Excel")]
    [LocalizedDisplayName("SheetNames")]
    [LocalizedDescription("SheetNames")]
    [Browsable(true)]
    [DefaultValue(null)]
    public string[]? SheetNames { get; set; }

     

    첫번째로 첫번째 행을 헤더로 사용하는지 여부입니다. 대부분 엑셀로 문서를 관리할 때 첫번째 행을 열의 제목으로 사용합니다. 그래서, 첫번째 행을 헤더로 사용하면 엑셀의 헤더인 A, B, C, D,... 대신 첫번째 행의 텍스트를 헤더로 사용하게 됩니다. 이 부분은 데이터에서 제외가 되므로 어떻게 사용할지 결정해야 합니다.

     

    두번째로 엑셀에서 데이터를 어떻게 수집할지에 대한 내용입니다. 일반적으로 데이터 수집은 데이터베이스에 질의문(Query)를 사용해서 가져오는데요. 엑셀의 경우에 사용자가 직접 질의문을 작성하기엔 무리가 있기 때문에 간단하게 처리할 수 있는 로직으로 제공해야 합니다. 데이터수집 방법은 총 4가지입니다. 엑셀에서 열방향을 먼저 처리하고, 행으로 내려갈지 또는 행으로 먼저 처리하고 다음 열로 넘어갈지를 선택하는겁니다.

    public enum TableDirection
    {
        ColumnRow = 0,
        RowColumn = 1,
        CustomHeaderColumnRow = 2,
        CustomHeaderRowColumn = 3
    }

     

    세번째 속성은 커스텀 헤더 설정인데요. 이 설정은 위의 TableDirection의 2번과 3번에 영향을 줍니다. 커스텀 헤더는 엑셀의 열 헤더인 A, B, C, D,...를 사용자가 직접 설정하는겁니다. 아무것도 설정하지 않으면 첫번째 열부터 데이터가 있는 모든 열의 값을 가져옵니다. 하지만, B와 D만 가져오고 싶으면 이 속성에 열 이름을 적어주면 됩니다. 마지막 네번째는 시트 이름을 사용자가 설정하는겁니다. 시트 이름을 설정하지 않으면 엑셀의 모든 시트에서 데이터를 수집합니다.

     

    대략적인 기능은 구현했으므로 이제 간단하게 테스트를 해봅시다. 테스트에서는 좀 더 복잡한 로직을 넣어볼건데요. 이전 포 반복에서 하려다가 안한거예요. 이번 테스트에서는 텍스트 파일에 저장된 내용을 하나씩 가져와서 텍스트 체크 액션으로 비교합니다. 그러다가 텍스트가 같으면 반복을 멈추고, 다른 로직으로 넘어가도록 할거예요. 매크로의 전체 구성은 아래와 같습니다.

    vlW1g1Y.jpeg

     

     

    매크로를 실행하고, 테스트한 내용은 아래 동영상을 참고하세요.

     

     

    테스트한 결과는 아래와 같습니다. a 변수로부터 오른쪽 값을 가져와서 test2인지 비교합니다. 결과가 True이기 때문에 아직 한번 더 반복해야 하는 반복기가 강제로 중지되고 액션이 이동했습니다. 이동한 b 액션이 스크립트의 마지막이기 때문에 b 그룹 액션이 실행되고, 매크로는 완료되었습니다.

    fTtTL74.jpeg

     

     

    오늘은 간단하게 텍스트 파일의 내용만큼 반복하는 방법을 알아봤는데요. 다음에는 엑셀 파일로 처리하는 방법을 알아볼께요. 엑셀 파일은 2차원 배열이기 때문에 텍스트 파일보다 처리 과정이 약간 더 복잡합니다. 그리고, 열과 행의 인덱스 또는 제목이 있어서 사용자가 임의로 선택할 수 있도록 했습니다. 자유도가 높은만큼 테스트하고 검증해야 할 내용이 많아서 3부에에서 자세하게 다뤄보도록 할께요^^

     

    개발자에게 후원하기

    MGtdv7r.png

     

    추천, 구독, 홍보 꼭~ 부탁드립니다.

    여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~

    감사합니다~

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.