NGMsoftware

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

    학습


    C# C# .NET 매크로 프로그램 만들기. (변수에 배열을 처리하는 방법)

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 오늘은 배열에 대해서 알아볼께요. 개발자라면 배열이 뭔지 알고 있을테고, 무엇을 하려는건지 감을 잡았을겁니다. 하지만, 엔지엠 매크로를 사용하시는 99프로는 개발자가 아닌 일반인이기 때문에 배열이 뭔지 이해하기가 쉽지 않을겁니다. 배열이란, 여러개의 항목을 가진 자료형을 말합니다. 자료형도 개발 언어라서 뭔지 이해가 안갈텐데요. 자료형은 데이터의 형식을 말합니다. 아래와 같은 것을 자료형이라고 합니다.

    • 문자 텍스트 (string): "안녕", "Hello", "매크로!", ...
    • 숫자 넘버 (integer, number): 100, 125, -75, ...
    • 실수 (double, float, decimal): 100.5, 0.9754, 0.00012578, ...
    • 객체 (object, ETC): element, object, user, car, boat, ...

     

    개발자가 아니기 때문에 이해할 필요는 없지만, 대략 저렇구나 하고 개념만 이해할 수 있으면 됩니다. 자~ 그러면 배열은 여러개의 자료형을 담는 그릇 정도로 생각하면 이해하기 좋을듯 합니다. 배열은 위에서 문자에 있는 하나하나를 함께 담고 있습니다. 우리가 눈으로 볼 때는 전부 하나의 데이터지만, 엑셀에서 셀에 들어 있는 데이터들의 집합 즉 배열로 이해해야 합니다. 잘 이해가 안갈텐데요. 일단, 개발을 완료하고 테스트를 해보면서 차이를 보면 금방 이해할 수 있을거예요. 그리고, 엔지엠 매크로 6에서도 이미 배열을 잘 사용하고 계신분들이 많습니다. 이 분들은 이미 알고 있는거죠^^

     

    엔지엠 매크로는 기본적으로 타입을 체크하지 않습니다. 내부적으로 타입을 가지고 있지만, 개발 편의를 위해 내부에서 저장된 데이터를 분석해서 자동으로 타입을 유추해서 처리해줍니다. 엔지엠 6에서는 문자, 숫자, 실수, 객체등등... 다양한 자료형이 있지만 사실 거의 사용되지는 않습니다. 앞서 말했듯이 자동으로 모두 처리해주기 때문입니다. 처음에는 프로그래밍 언어들처럼 자료형을 엄격하게 검사하고, 자료형이 다르면 데이터를 주고 받을 수 없도록 했는데요. 대부분의 사용자가 일반인 분들이라서 스트롱 타입을 강제하는건 좋지 않은 판단이었습니다.

     

    변수 액션에 새로운 속성이 하나 추가되었고, 기본 값 속성에는 멀티 라인을 처리할 수 있는 어트리뷰트(Attribue: 특성)를 추가했습니다.

    [LocalizedCategory("Action")]
    [LocalizedDisplayName("InitValue")]
    [LocalizedDescription("InitValue")]
    [Browsable(true)]
    [DefaultValue(null)]
    [Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))]
    public string? DefaultValue { get; set; }
    
    [LocalizedCategory("Action")]
    [LocalizedDisplayName("IsArray")]
    [LocalizedDescription("IsArray")]
    [Browsable(true)]
    [DefaultValue(false)]
    public bool IsArray { get; set; }

     

    엔지엠 6 매크로와 다르게 인공지능 매크로인 엔지엠 7에서는 자료형에 관련된 모든 속성이 사라졌고, 좀 더 심플하게 작업할 수 있게 되었습니다. IsArray 옵션으로 사용자가 입력한 데이터가 배열인지 아닌지를 판단합니다. 이 부분은 아래 테스트에서 좀 더 자세하게 알아보도록 할께요. 처리 로직은 심플합니다. 이전 버전에 비하면 정말 많은 부분에서 복잡하게 처리되었던 로직들이 사라졌습니다.

    if (IsGlobal)
        variables = player.Manager.Variables;
    else
    {
        if (player.HasParent && IsParent)
            variables = player.Parent?.Variables;
        else
            variables = player.Variables;
    }
    
    if (IsArray && !string.IsNullOrEmpty(DefaultValue))
    {
        var datas = DefaultValue.Replace(Environment.NewLine, "\\n").Split("\\n");
        variables?.AddOrUpdate(ID, datas, (key, value) => datas);
    }
    else
        variables?.AddOrUpdate(ID, DefaultValue ?? string.Empty, (key, value) => DefaultValue ?? string.Empty);

     

    테스트를 위해 포이치(Foreach) 반복 액션에 배열을 처리할 수 있는 속성도 추가 했습니다. 이전 시간에 만들었을 때는 Text, Excel, CSV와 같은 파일에서 데이터를 추출하고, 이 데이터로 반복할 수 있도록 처리 했습니다. 어차피 반복 로직은 이미 다 만들었기 때문에 반복할 데이터 처리 부분만 개선하면 될거 같네요. 아래 속성은 파일이 아닌 변수로부터 배열을 받아올 때 사용합니다.

    [LocalizedCategory("Array")]
    [LocalizedDisplayName("RepeatData")]
    [LocalizedDescription("RepeatData")]
    [Browsable(true)]
    [DefaultValue(null)]
    public string[]? ArrayData { get; set; }

     

    이미 메모리에서부터 배열 자료형이기 때문에 딱히 파싱(Parsing)할 로직은 필요하지 않습니다.

    case Definition.FileType.Csv:
        if (TableDirection == Definition.TableDirection.CustomHeaderColumnRow || TableDirection == Definition.TableDirection.CustomHeaderRowColumn)
        {
            player.Manager.Output.WriteLine($"[{TableDirection.ToString()}] {player.Manager.Client.ResxMessage.GetString("NotSupportOption")}", log4net.Core.Level.Warn);
            return 0;
        }
    
        _datas = ExcelExt.Manager.ReadCsv(SelectDataSource, UseHeader, TableDirection, CustomColumns, ColumnSeparator);
        break;
    case Definition.FileType.Excel:
        _datas = ExcelExt.Manager.Read(SelectDataSource, UseHeader, TableDirection, CustomColumns, SheetNames);
        break;
    case Definition.FileType.Array:
        if (ArrayData != null && ArrayData.Count() > 0)
            _datas = ArrayData.ToList();

     

    예외 처리와 방어 코드도 작성해야 하겠지만, 디테일은 나중에 처리하기로 하고 지금은 동작하게끔만 간단하게 작성했습니다. 스크립트는 간단합니다.

    AFbrXkH.png

     

     

    이 테스트의 시나리오는 변수에 문자열 데이터를 배열 형태로 입력하고, 포이치 반복으로 배열의 항목을 하나씩 출력합니다. 변수 초기 값에 아래와 같이 한줄에 하나씩 입력하세요.

    7vLOLla.png

     

     

    포이치 반복 액션에서 반복할 데이터를 변수로부터 받아와야 합니다. 아래 그림과 같이 변수 카테고리에서 변수 가져오기를 클릭하고, 변수 이름을 선택해줍니다. 그러면, 해당 변수에 있는 데이터를 포이치 반복 액션의 속성으로 가져올 수 있습니다. 여기에서는 배열 데이터로 가져왔습니다. 이 데이터로 포이치 반복이 돌아갑니다.

    nfLK0Xu.png

     

     

    포이치 반복 안에는 반복하는 동안 수행되어야 할 액션들을 포함합니다. 여기에서는 출력 액션이 하나 추가되어 있는데요. 변수에 추가한 내용을 하나씩 출력해줍니다. 포이치 반복은 한번 실행될 때마다 항목 하나하나 결과 값으로 가져옵니다. 변수에 결과 값을 저장해줍니다. 그래야, 포이치 안에 있는 액션들이 데이터를 가져다가 쓸 수 있습니다. 참고로, array 변수의 데이터 타입은 배열입니다. 그런데, 배열의 데이터 하나인 문자로 덮어쓰기 한건데요. 원본 데이터를 건드리지 않고 처리하려면 항목 하나를 저장할 수 있는 변수가 하나 더 필요합니다.

    qktLzQk.png

     

     

    변수에 저장된 데이터 하나를 출력 액션에서 가져와서 에디터 하단의 출력창에 표시해줍니다.

    OPmwLfk.png

     

     

    완성된 매크로를 실행 해볼까요? 아래 동영상과 같이 테스트 해보고, 결과를 확인 해봅시다. 배열과 문자열은 다르게 처리됩니다. 배열은 항목 수 만큼 반복하면서 처리하지만, 배열이 아닌 경우에는 한번만 처리하고 매크로가 완료됩니다. 배열이 중요한 이유는 다양한 환경에서 반복 처리가 필요하기 때문입니다. 예를 들어서, 데이터베이스에 사용자가 100명 있다고 생각 해보세요. 여기서, 매칭되는 몇명만 추려서 뭔가 처리하고 싶을 때 유용하게 사용할 수 있습니다.

     

     

    이외에도 카카오톡 가리기봇이나 강퇴봇을 만들 때 일부 사용자는 강퇴에서 제외시키거나 그럴 때 사용자 목록의 값을 모두 하나씩 비교하면서 건너뛸 수 있도록 매크로를 구성해야 합니다. 포 반복(For Repeat)을 사용해도 되지만, 포 반복은 인덱싱을 처리해야 하고 인덱싱된 위치의 값을 가져오도록 액션을 처리해줘야 합니다. 인덱싱에 어떤 조건이 필요한게 아니라면 포이치 반복을 사용하는게 더 효율적입니다. 그리고, 앞에서 배운대로 비동기로 처리하면 좀 더 퍼포먼스가 좋아질 수 있습니다.

     

    개발자에게 후원하기

    MGtdv7r.png

     

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

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

    감사합니다~

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

    댓글목록

    등록된 댓글이 없습니다.