NGMsoftware

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

    학습


    C# C# .NET 매크로 프로그램 만들기. (배열 삭제 및 수정하기 3부)

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 배열 관련 액션의 마지막 내용입니다. 이번에는 배열 데이터에서 특정 위치의 값을 삭제하거나 수정하는 방법을 알아볼건데요. 이미 배열을 처리하는 기능을 모두 만들어 두었기 때문에 배열 수정 및 삭제는 간단하게 처리할 수 있습니다. 우선, 아래와 같이 수정 모델과 삭제 모델을 만들어야 합니다.

     

    아래 솔루션에서 프레임워크의 모델안에 아래 그림처럼 2개의 클래스를 추가 했습니다.

    8Gd3CBk.png

     

     

    using은 참조하는 라이브러리만 추가하고, 나머지는 제거합니다.

    using Ai.Interface;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Drawing.Design;

     

    사용자가 배열 데이터에서 원하는 값을 변경하기 위해 기본적으로 제공해야 할 속성들입니다.

    [NonSerialized]
    private string[]? _datas;
    
    [LocalizedCategory("Data")]
    [LocalizedDisplayName("Result")]
    [LocalizedDescription("Result")]
    [Browsable(true)]
    [DefaultValue(null)]
    public string[]? Result { get; set; }
    
    [LocalizedCategory("Array")]
    [LocalizedDisplayName("RepeatData")]
    [LocalizedDescription("RepeatData")]
    [Browsable(true)]
    [DefaultValue(null)]
    public string[]? ArrayData { get { return _datas; } set { _datas = value; } }
    
    [LocalizedCategory("Action")]
    [LocalizedDisplayName("EditValues")]
    [LocalizedDescription("EditValues")]
    [Browsable(true)]
    [DefaultValue(null)]
    [Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))]
    public string? EditValues { get; set; }
    
    [LocalizedCategory("Array")]
    [LocalizedDisplayName("ArrayAddLocation")]
    [LocalizedDescription("ArrayAddLocation")]
    [Browsable(true)]
    [DefaultValue(typeof(Ai.Definition.FindOption), "Last")]
    public Ai.Definition.FindOption EditLocation { get; set; } = Definition.FindOption.Last;
    
    [LocalizedCategory("Array")]
    [LocalizedDisplayName("ArrayIndex")]
    [LocalizedDescription("ArrayIndex")]
    [Browsable(true)]
    [DefaultValue(0)]
    public int Index { get; set; }

     

    처리 로직도 크게 어려운건 없습니다. 변수에 저장되어 있는 배열 데이터를 가져와서 사용자가 선택한 위치의 값을 변경하기만 하면 됩니다.

    public override string? Execute(IPlayer player)
    {
        var id = base.Execute(player);
    
        List<string>? datas = _datas.ToList();
    
        switch (EditLocation)
        {
            case Definition.FindOption.First:
                datas[0] = EditValues;
                break;
            case Definition.FindOption.Last:
                datas[datas.Count - 1] = EditValues;
                break;
            case Definition.FindOption.Index:
                datas[Index] = EditValues;
                break;
        }
    
        Result = datas.ToArray();
    
        return id;
    }

     

    코드량이 얼마 되지 않는군요. 사실, 액션 하나하나는 크게 어렵지 않습니다. 다만, 이런 액션들을 유기적으로 조합하고 관리하면서 처리할 수 있도록 하는 매크로 엔진이 가장 어려운 부분입니다. 우리는 이미 매크로 엔진과 코어 엔진을 모두 만들어 두었기 때문에, 간단하게 모델만 추가함으로써 자동으로 매크로가 동작할 수 있는 시스템을 갖추었습니다. 보통 이런 시스템을 프레임워크라고 부르는데요. 엄밀히 말하면 개발한 코드 또는 모듈이 틀에 맞게 동작하도록 하는 것을 말합니다.

     

    엔지엠 매크로는 크게 프레임워크 안에 엔진이 있고, 엔진이 사용하는 리소스와 공통 라이브러리를 가집니다. 그리고, 실제로 동작을 수행하는 모든 액션들은 모델이 담당하는 간단한 구조로 되어 있습니다. 그렇기 때문에 어떤 문제가 발생했을 때 엔진을 먼저 확인하고, 그 다음에 왜 이렇게 동작하게 되었는지를 모델에서 체크해야 합니다. 이 부분은 개발자가 확인할 수 있는 부분이고, 그 외에 사용자는 매크로 에디터에서 출력해주는 로그를 분석해야 합니다.

     

    이제 배열 변수의 내용을 변경할 수 있는지 테스트를 해볼께요. 테스트 내용은 아래 동영상을 참고 해주세요.

     

     

    이번에는 배열에서 특정 위치의 값을 삭제 해볼께요. 이 기능은 좀 더 개선해야 할거 같긴한데요. 특정 범위의 값으로 삭제하고 싶을거 같거든요. 하나만 삭제하는건 뭐랄까... 핵심 기능이 빠진듯한 느낌입니다. 그래서, 계속 신경 쓰이지만 다른 기능 개발이 더 급하기 때문에 추후에 요구 사항이 나오면 개선하거나 리팩토링을 통해서 정리를 한번 하는게 좋을거 같아요. 일단 빨리 진도를 빼고, 개선하는게 좋은 방법이거든요. 저만의 생각일까요? ㅎㅎ;

     

    배열 삭제 액션이 제공하는 속성들입니다. 배열 수정과 크게 차이는 없습니다. 기본 구조가 동일하니까요.

    [NonSerialized]
    private string[]? _datas;
    
    [LocalizedCategory("Data")]
    [LocalizedDisplayName("Result")]
    [LocalizedDescription("Result")]
    [Browsable(true)]
    [DefaultValue(null)]
    public string[]? Result { get; set; }
    
    [LocalizedCategory("Array")]
    [LocalizedDisplayName("RepeatData")]
    [LocalizedDescription("RepeatData")]
    [Browsable(true)]
    [DefaultValue(null)]
    public string[]? ArrayData { get { return _datas; } set { _datas = value; } }
    
    [LocalizedCategory("Array")]
    [LocalizedDisplayName("ArrayRemoveLocation")]
    [LocalizedDescription("ArrayRemoveLocation")]
    [Browsable(true)]
    [DefaultValue(typeof(Ai.Definition.ArrayOption), "Last")]
    public Ai.Definition.ArrayOption RemoveLocation { get; set; } = Definition.ArrayOption.Last;
    
    [LocalizedCategory("Array")]
    [LocalizedDisplayName("ArrayIndex")]
    [LocalizedDescription("ArrayIndex")]
    [Browsable(true)]
    [DefaultValue(0)]
    public int Index { get; set; }
    
    [LocalizedCategory("Array")]
    [LocalizedDisplayName("ArrayValue")]
    [LocalizedDescription("ArrayValue")]
    [Browsable(true)]
    [DefaultValue(0)]
    public string? Value { get; set; }

     

    처리 로직은 어떻게 삭제해야 하는지 옵션에 따라서 아래와 같이 switch ~ case로 분기하여 각각 처리했습니다.

    public override string? Execute(IPlayer player)
    {
        var id = base.Execute(player);
    
        List<string>? datas = _datas.ToList();
    
        switch (RemoveLocation)
        {
            case Definition.ArrayOption.First:
                datas.RemoveAt(0);
                break;
            case Definition.ArrayOption.Last:
                datas.RemoveAt(datas.Count - 1);
                break;
            case Definition.ArrayOption.Index:
                datas.RemoveAt(Index);
                break;
            case Definition.ArrayOption.Values:
                datas.RemoveAll(x => x == Value);
                break;
            case Definition.ArrayOption.FirstValue:
                datas.RemoveAt(datas.IndexOf(Value));
                break;
                case Definition.ArrayOption.LastValue:
                datas.RemoveAt(datas.LastIndexOf(Value));
                break;
            case Definition.ArrayOption.Clear:
                datas.Clear();
                break;
        }
        
        Result = datas.ToArray();
    
        return id;
    
    }

     

    딱히 설명할만한 내용이 없습니다. 각각의 함수명을 보면 대략 어떻게 동작할지 유추할 수 있거든요. 그리고, 메소드가 넘겨 받는 인자 값 유형과 명칭으로 동작을 파악하는데 도움이 됩니다. 그래서, 프로그램? 소프트웨어? 아무튼 어떤 제품(Product)이나 서비스(Server)를 코딩할 때 작명이 엄청 중요합니다. 혼자 개발하면야 대충 지어도 되지만 협업하는 환경에서는 중요하죠. 그리고, 혼자 개발하더라도 몇일 지나면 코드를 까먹기 때문에 이름으로 알아볼 수 있도록 작명을 잘하는게 중요해요. 개발자의 가장 큰 덕목중에 하나가 작명 센스거든요^^;

     

    이제 만들어진 액션을 테스트 해보도록 하겠습니다. 테스트 방식과 결과는 아래 동영상을 확인 해보시면 될거 같아요.

     

     

    동영상 편집을 위해서 마이크를 하나 구입했습니다. 모양은 그럴싸한데~ 성능은 약간 아쉬워요. 그래도, 4만원짜리 PC용 마이크 치고는 괜찮지 않나하는 생각이 듭니다. 비싼걸 써보지는 못했지만, 그전에 핸드폰용 핀 마이크를 사용해서 녹음을 했던적이 있거든요. 그거에 비하면 아주 양반입니다. 볼륨 조절도 되고 주변 바람소리나 잡음이 아주~ 조금이지만 잡아주는거 같거든요.

     

    혼자서 떠드는게 참 쉽지 않는 일입니다. 특히나 대본을 적어놓고 뭔가 체계적으로 하는게 아니다보니 더 그런거 같습니다. 평생 개발만 하다가 나도 모르게 개인 사업자가 되고, 이제는 유튜브까지 하다니... 세월이 참 빠르고, 격세지감을 느끼고 있는 요즘입니다. 사람은 멈추면 고이고, 행동하면 발전한다고 하는데요. 잠시 고여 있던 시기도 있었지만 앞으로는 다시 일어나서 달려야겠어요. 시간을 더 많이 써야 하는 일들이 많아지고 있지만, 어쩌겠어요~ 먹고 살려면 달려야죠^^

     

    이 글이 도움이 되셨다면~ 커피 한잔이라도 후원 부탁드립니다^^

    개발자에게 후원하기

    MGtdv7r.png

     

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

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

    감사합니다~

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

    댓글목록

    등록된 댓글이 없습니다.