더 짧아진 Which 함수 EXCEL/VBA/VBS

지난 번 포스팅에서 말한 더 개선한 which함수를 조금 더 개선해보았다. 지난 번에는 Enum을 사용하다보니 select case문이 비교연산의 갯수에 비례하여 커졌다. 이번에는 이넘도 저넘도 필요없다. 연산자를 문자열로 전달하면 된다.

이렇게 짧아진 이유는 Application.Evaluate() 덕분이다. Application.Evaluate()은 문자열로 표시된 수식을 평가하여 적절한 결과를 돌려준다.
Function which2(array_values, oper As String, lookup) As Long()
Dim i As Long, lb As Long, ub As Long
Dim index() As Long, cnt As Long

lb = LBound(array_values)
ub = UBound(array_values)

For i = lb To ub
If Application.Evaluate(array_values(i) & oper & lookup) Then
ReDim Preserve index(cnt)
index(cnt) = i
cnt = cnt + 1
End If
Next

If cnt = 0 Then
ReDim index(0)
index(0) = -1
End If

which2 = index
End Function

Sub demo_which2()
Dim values
Dim value

values = Array(96, 10, 18, 77, 49, 76, 67, 71, 74, 45, 43, 24, 18, 30, 57, 73, 78, 2, 92, 12)
value = 50

Dim idx() As Long, i As Long, lb As Long, ub As Long

idx = which2(values, ">=", value)

lb = LBound(idx)
ub = UBound(idx)

For i = lb To ub
Debug.Print idx(i)
Next
End Sub

간단한 다차원 배열 정렬 EXCEL/VBA/VBS

보통 정렬을 하는 경우 벡터형태의 배열 즉 (n x 1) 형태의 데이터만 다루게 된다. 그러나 종종 워크시트상의 정렬처럼 (n x m)형태의 배열을 정렬할 필요가 생긴다. 이러한 행렬형태의 데이터를 정렬을 만드는 일은 약간 골치거리이다. 몇 번째 컬럼을 key 로 둘 것인지를 정하게 해주고, key는 몇 개까지 가능할 지, 오름차순/내림차순도 신경써야 하고...

그러나 정렬이 필요한 다차원 배열을 고려한다면 우선 사용자 정의 데이터형을 만들고, 이것의 1차원 배열을 선언하는 편이 쉽다.
가령 종목코드, 종목명, 종가로 된 데이터를 사용하고 정렬하는 경우를 살펴보면
우선 다음과 같은 사용자 정의 데이터 형식을 선언한다.
Type OwnDataType
Symbol As String
SName As String
ClosePrice As Long
End Type
그리고 Dim d(9) As OwnDataType 과 같이 사용자 정의 데이터형식의 배열을 선언하고 정렬을 한다. 정렬의 핵심원리는 비교연산의 결과에 따라 다음과 같이 사용자 정의 데이터 형식의 데이터를 맞교환하면

Temp = Data(i)
Data(i) = Data(j)
Data(j) = Temp

내부의 데이터(가령 Symbol, SName, ClosePrice)도 따라 움직이는 것이다.

아래의 Sort()프로시저에서는 내림차순 정렬을 위한 비교(Data(i).ClosePrice < Data(j).ClosePrice)를 하고 Temp 변수를 이용하여 데이터를 교환하는 것이다. 이때 Temp도 Data와 같은 종류의 데이터이다( 내림차순 정렬은 >를 사용한다 )
Sub Sort(ByRef Data() As OwnDataType)

Dim lb As Long, ub As Long
Dim i As Long, j As Long, Temp As OwnDataType

lb = LBound(Data)
ub = UBound(Data)

For i = lb To ub - 1
For j = i + 1 To ub
If Data(i).ClosePrice < Data(j).ClosePrice Then
Temp = Data(i)
Data(i) = Data(j)
Data(j) = Temp
End If

Next
Next
End Sub

다음의 demoSort 는 위의 정렬프로시저 Sort 의 사용예 이다.
Sub demoSort()
Dim d(9) As OwnDataType

d(0).Symbol = "A000020": d(0).SName = "동화약품": d(0).ClosePrice = 4715
d(1).Symbol = "A000040": d(1).SName = "S&T모터스": d(1).ClosePrice = 680
d(2).Symbol = "A000050": d(2).SName = "경방": d(2).ClosePrice = 118000
d(3).Symbol = "A000060": d(3).SName = "메리츠화재": d(3).ClosePrice = 10350
d(4).Symbol = "A000070": d(4).SName = "삼양사": d(4).ClosePrice = 60500
d(5).Symbol = "A000080": d(5).SName = "진로": d(5).ClosePrice = 35800
d(6).Symbol = "A000100": d(6).SName = "유한양행": d(6).ClosePrice = 152000
d(7).Symbol = "A000120": d(7).SName = "대한통운": d(7).ClosePrice = 105000
d(8).Symbol = "A000140": d(8).SName = "하이트홀딩스": d(8).ClosePrice = 16800
d(9).Symbol = "A000150": d(9).SName = "두산": d(9).ClosePrice = 134500

Call Sort(d())

Dim i As Long

For i = LBound(d) To UBound(d)
Debug.Print i, d(i).Symbol, d(i).SName, d(i).ClosePrice
Next

End Sub

OCaml을 편하게 사용하기 OCAML/F#

OCaml 을 보니 문득 비슷한 애가 하나 떠오른다. 걔도 O씨 집안이다. 바로 Octave. Octave는 Matlab의 Clone으로 널리 알려진 행렬연산 소프트웨어인데, 달랑 명령 프롬프트만 껌뻑 껌뻑 거리는 극악의 환경이다. 외부 에디터를 이용해 스크립트 만들고 명령프롬프트 하나 뛰어 놓고 입력하면 되지만 배우는 처지에선 자동코드완성, 인텔리센스(intellisense in action), 도움말, 디버깅 등등 필요한 게 많다.

좀 더 편리한 환경에서 하면 좀 배우기 수월할 것 같아서(솜씨없는 목수가 연장 탓하지만) IDE 를 검색했더니 Eclipse에 애드인 형태로 사용할 수 있단다. 그러나 느려서 답답했던 기억이 나서 패스. 한 가지 대안으로 떠오른 건 F#. F# 은 MS에서 OCaml을 바탕으로 만든 함수형 언어이다. 따라서 OCaml과 완전히 같진 않아도 어느 정도 이걸 익히는 데 도움이 될 것이다. 여러 함수형 언어중 MS가 OCaml을 선택한 것은 OCaml이 그만큼 괜찮은 넘이라는 반증이 아니까? 또한 닷넷의 리소스를 이용하면 편리할 것이다. 가령 다음처럼
let rec sum n=
if n>1 then sum (n-1)+n
else 1
let x=sum 10
System.Console.Write(x)
Visual Studio 2010 pro 버전이상이면 편하게 F# 을 할 수 있는데, 공짜로 쓸 수 있는 IDE 를 찾아보니 Visual F# CTP 와 Visual Studio 2010 Integrated Shell 의 조합이면 무료 IDE 가 된다는 것이다. 아래의 F# 홈페이지에 가서


Visual Studio 2010 Integrated Shell를 먼저 설치한 후 Visual F# CTP 를 설치하시길... 아래와 같이 새 프로젝트를 시작하면 F# project template을 볼 수 있다. 편리한 기능중 하나는 에디터에서 일부 코드를 [F# Interactive]라는 콘솔로 보낼 수 있다는 것이다. 전체 실행을 하지 않아도 콘솔에서 일부코드를 확인해볼 수 있다. 마치 RStudio와 같은 느낌인데...


1 2 3 4 5 6 7 8 9 10 다음