this , this 및 this question 과 유사하게 ...
골프에 대한 일반적인 팁은 무엇입니까 VBA
? 나는 일반적으로 다소 특정한 코드 골프 문제에 적용될 수있는 아이디어를 찾고 있습니다 VBA
(예 : "댓글 제거"는 답이 아닙니다). 답변 당 하나의 팁을 게시하십시오.
다른 언어로 작업했지만 가장 VBA
강하고이 VBA
사이트에서 많은 골퍼를 사용 하는 것을 보지 못했습니다 .
this , this 및 this question 과 유사하게 ...
골프에 대한 일반적인 팁은 무엇입니까 VBA
? 나는 일반적으로 다소 특정한 코드 골프 문제에 적용될 수있는 아이디어를 찾고 있습니다 VBA
(예 : "댓글 제거"는 답이 아닙니다). 답변 당 하나의 팁을 게시하십시오.
다른 언어로 작업했지만 가장 VBA
강하고이 VBA
사이트에서 많은 골퍼를 사용 하는 것을 보지 못했습니다 .
답변:
ByRef
잠수함을 호출 할 때 기본경우 Sub
에 따라 대신 전화 를 사용하는 것이 가능 합니다Function
몇 개의 추가 문자를 저장하기 위해 ...
이쪽 ( 87 문자)
Sub a()
b = 0
Do Until b = 5
b = c(b)
Loop
End Sub
Function c(d)
c = d + 1
End Function
( 73 자) 로 다시 작업 할 수 있습니다 :
Sub a()
b = 0
Do Until b = 5
c b
Loop
End Sub
Sub c(d)
d = d + 1
End Sub
이 값이 영구적으로 반복 되지 는 않지만 b
의 값을 다시 할당하지 않는 것 같습니다 .
위의 방법은 Function
호출을 사용하지 않고 호출의 ByRef
( "기준으로") 기능을 이용합니다 Sub
. 이것이 의미하는 것은 전달 된 인수는 호출 함수에서와 같은 변수입니다 ( ByVal
"By Value"전달 (복사본) 와 반대 ). 전달 된 변수를 수정하면 호출 함수로 다시 변환됩니다.
기본적으로 vba 는 모든 인수를로 사용 ByRef
하므로이를 정의하기 위해 문자를 사용할 필요가 없습니다.
위의 예제는 함수의 반환 값에 따라 완벽하게 변환되지 않을 수 있습니다. (예 : 전달 된 것과 다른 데이터 유형을 반환), 그래도 원래 변수를 수정하는 동안 반환 값을 얻을 수 있습니다.
예를 들면 다음과 같습니다.
Sub a()
b = 0
Debug.Print c(b) ' This will print 0, and b will equal 1.'
End Sub
Function c(d)
c = d
d = d + 1
End Function
직접 실행 창은 유효한 VBA 실행 문을 평가합니다. 코드 편집기에서와 같이 직접 실행 창에 명령문을 입력하기 만하면됩니다. VBA 코드를 빠르게 실행하며 다음과 같은 이유로 많은 추가 문자를 저장할 수 있습니다.
다음은 직접 실행 창에있는 tag code-golf로 PPCG의 게시물에 응답하는 VBA 코드의 예입니다 . A가없는 Letter A
?Chr(88-23);
Joffan이 답변했습니다 .
크레딧 이미지 : Excel Campus
a="value":?a
먼저의 값을 설정 a
한 다음 인쇄합니다.
루프와 함께 사용하면 일부 조건부 검사가 중복됩니다. 예를 들어 For
시작 조건이 실행 조건 범위를 벗어나면 루프가 처리되지 않습니다.
다시 말해, 이것은 ( 49 문자) :
If B > 0 Then
For C = A To A + B
'...
Next
End If
이것으로 바꿀 수 있습니다 ( 24 자) :
For C = A To A + B ' if B is 0 or less, then the code continues past Next, unabated.
'...
Next
대부분의 경우 VBA에서는 Option Explicit
(기본적으로 생략되어 있음) 생략하고 건너 뛸 수 있습니다.Dim
많은 변수를 수 있습니다.
이렇게하면 ( 96 문자) :
Option Explicit
Sub Test()
Dim S As String
Dim S2 As String
S = "Test"
S2 = S
MsgBox S2
End Sub
이것이됩니다 ( 46 문자) :
Sub Test()
S = "Test"
S2 = S
MsgBox S2
End Sub
특정 객체 (예 : 배열)를 사용해야하는 경우에도 Dim
해당 변수 가 필요할 수 있습니다 .
Evaluate()
과 []
앞에서 지적했듯이 대괄호 [A1]
표기법을 사용하여 하드 코딩 된 범위 통화를 줄일 수 있습니다 . 그러나 그것보다 더 많은 용도가 있습니다.
MSDN documentation 에 따르면 이 Application.Evaluate()
방법은 단일 인수를 취합니다.Name
Microsoft Excel의 명명 규칙에 정의 된대로 .
마지막에 다루는 몇 가지 중요한 차이점이 있지만 NB [string]
는 줄임말 Evaluate("string")
( ""
문자열 데이터 유형을 나타내는 음성 표시 참고 )입니다.
그렇다면 사용법의 의미는 무엇입니까?
기본적 [some cell formula here]
으로 Excel 워크 시트에서 셀을 나타내며 셀에 거의 아무것도 넣지 않고 일반 셀로 할 수있는 것을 얻을 수 있습니다
예제와 함께 요약하면
[B7]
해당 셀에 대한 참조를 반환합니다?[B7].Address
반환"B$7$"
[A1:B5]
A1:B5
(범위)에 대한 범위 참조를 반환합니다.[A1:B5 A3:D7]
A3:B5
(교차)에 대한 범위 참조를 반환합니다.[A1:B5,C1:D5]
A1:D5
(기술적으로 A1:B5,C1:D5
) (Union)에 대한 범위 참조를 반환합니다.[myRange]
A1 : G5 와 같은 사용자 정의[Table1]
(코드 골프에는 덜 유용 할 수 있음)Evaluate()
또는[]
[SUM(1,A1:B5,myRange)]
myRange 범위의 값에 대한 산술 합을 반환합니다. 여기에서 VBA 변수가 아닌 통합 문서 이름을 나타냅니다.[IF(A1=1,"true","false")]
(vba에 비해 1 바이트 짧음 Iif([A1]=1,"true","false")
)[CONCAT(IF(LEN(A1:B7)>2,A1:B7&" ",""))]
-길이가 2보다 큰 범위의 모든 문자열을 공백으로 결합합니다.!
연산자를 사용하여 셀 또는 다른 통합 문서에 정의 된 이름을 참조 할 수 있습니다[[BOOK1]Sheet1!A1]
BOOK1 또는 A1의 범위 참조 반환 ['[MY WORKBOOK.XLSM]Sheet1!'A1]
동일한에서 대를MY WORKBOOK
'
(자신의 이름에 공백 및 기본라는 이름의 통합 문서에 대한 확장의 부족으로 통합 문서 BOOK+n
)NB 나는이 정보에 대해 SO에 대해 질문을 했으므로 더 나은 설명을 위해 거기 를 살펴보십시오.
들어오는 것과 비슷하게 나오는 것은 워크 시트 셀이 반환 할 수있는 모든 것을 포함합니다. 다음은 표준 Excel 데이터 형식 및 해당 VBA 형식입니다.
Boolean
)String
)Double
)Variant/Error
) (이것은 오류 가 아닌 오류입니다. 즉, 코드 실행을 중단하지 않고 ?[1/0]
정상적으로 실행됩니다)그러나 셀이 할 수없는 몇 가지 반환 할 수있는 것들이 있습니다.
Range
) (위 섹션 참조)Variant()
)표시된 것처럼 []
표준 Excel 데이터 형식 중 하나를 반환하는 배열 수식을 평가하는 데 사용할 수 있습니다. 예를 들어 [CONCAT(IF(LEN(A1:B7)>2,A1:B7&" ",""))]
어떤 돌아갑니다 Text
. 그러나 형식의 Evaluate
배열을 반환 할 수도 있습니다 Variant
. 이것들은
하드 코드 :
[{1,2;3,4}]
-2D 배열을 출력합니다 ,
. 열 구분 기호이며 ;
행을 구분합니다. 1D 배열을 출력 할 수 있습니다
배열 공식 :
[ROW(A1:A5)]
-2D 배열을 출력합니다 {1,2,3,4,5}
. 즉 (2,1)은 두 번째 항목입니다 (그러나 일부 함수는 1D 배열을 출력합니다)
[LEN(A1:A5)]
범위의 첫 번째 셀에있는 텍스트의 길이 만 출력합니다
Split([CONCAT(" "&LEN(A1:A5))])
첫 번째 항목이 비어있는 1D 배열 0 ~ 5를 제공합니다.
[INDEX(LEN(A1:A5),)]
또 다른 해결 방법입니다. 기본적으로 RAND()
워크 시트 수식을 휘발성으로 만들기 위해 의미없는 것을 추가하는 것과 마찬가지로 원하는 배열 반환 동작을 얻으려면 배열 처리 함수를 사용해야합니다 .
Evaluate()
vs []
몇 가지 차이점 사이에 있습니다 Evaluate()
및 []
인식하려면
Evaluate("SUM(B1,1,"&v &",2)")
요약 것이다 [B1]
, 1
, 2
및 변수를v
배열
배열을 반환 할 때 Evaluate 만 배열 인덱스와 함께 사용할 수 있으므로
v=Evaluate("ROW(A1:A5)")(1,1) ''#29 bytes
에 해당
i=[ROW(A1:A5)]:v=i(1,1) ''#23 bytes
i=[ROW(A1:A5)]:v=i(2,1):?v
Next
문Next:Next:Next
응축 될 수 있습니다
Next k,j,i
에 대한 반복자 곳 For
루프가 i
, j
그리고 k
- 순서이다.
예를 들어 아래 (69 바이트)
For i=0To[A1]
For j=0To[B1]
For k=0To[C1]
Debug.?i;j;k
Next
Next
Next
65 바이트로 압축 될 수 있음
For i=0To[A1]
For j=0To[B1]
For k=0To[C1]
Debug.?i;j;k
Next k,j,i
그리고 이것이 형식 및 들여 쓰기에 미치는 영향에 관해서는, 이것을 처리하는 가장 좋은 방법은 다음 명령문을 가장 외부 명령문과 정렬시키는 것입니다. 예 :
For i=0To[A1]
For j=0To[B1]
For k=0To[C1]
Debug.?i;j;k
Next k,j,i
If
진술 감소조건부 If ... Then ... Else
검사를 사용하여 변수를 할당 할 때 End If
전체 검사를 한 줄로 수행 하여 코드를 제거함으로써 사용되는 코드의 양을 줄일 수 있습니다 .
예를 들면 다음과 같습니다 ( 37 자).
If a < b Then
c = b
Else
c = a
End If
이것으로 줄일 수 있습니다 ( 30 자)
If a < b Then c = b Else c = a
중첩 조건이 둘 이상인 경우 다음과 같이 최소화 할 수 있습니다.
If a Then If b Then If c Then Z:If d Then Y:If e Then X Else W Else V:If f Then U 'Look ma! No "End If"!
(가) 주 :
당신이 내 줄 이상 / 명령을 추가 할 수 있습니다 If
블록.
이와 같은 간단한 경우, 일반적으로 확인 Else
전에 변수를 설정하여를 제거 할 수도 있습니다 If
( 25 자).
c = a
If a < b Then c = b
더 나은 방법은 위의 IIf()
함수 ( 20 자)를 사용하여 이것으로 더 줄일 수 있습니다 .
c = IIf(a < b, b, a)
Range("A1")
전화를 줄이고 좋아Range("A1").Value
(17 바이트)와 더 간단한 Range("A1")
(11 바이트)을 [A1]
(4 바이트) 로 줄일 수 있습니다
[]
에서 대체 Evaluate()
를 사용하는 것은 단순히 범위 통화보다 훨씬 다양합니다. 예 : 당신은 대체하는 데 사용할 수 있습니다 WorksheetFunction.FuncName(args)
와 함께 단지 [FuncName(args)]
, 같은 ?[SUMPRODUCT({1,3,5},{2,7,-1})]
또는 매우 유용 [MIN(1,2,3)]
/[MAX(1,2,3)]
Evaluate("str")
또는 속기 [str]
는 VBA에서 매우 강력하며 최근에 알게 된 사실이며 골프에도 도움이 될 것입니다!
VBA는 실제로 필요하지 않은 간격을 추가하기 위해 자동 서식을 설정합니다. 메타에 대한 대답 이 있는데 왜 우리가 자동 포맷팅으로 추가 된 바이트를 할인 할 수 있는지 이해할 수 있습니다. 그래도 너무 많이 제거하지 않았는지 항상 확인하는 것이 중요합니다. 예를 들어, 다음 은 공백을 제거하여 거의 22 % 감소한 내 대답입니다 .
원본 버전 : (188 바이트)
Sub g(n)
For i = 0 To 1
For x = -3 To 3 Step 0.05
y = n ^ x * Cos(Atn(1) * 4 * x)
If y < m Then m = y
If i = 1 Then Cells(500 * (1 - y / m) + 1, (x + 3) * 100 + 1) = "#"
Next
Next
End Sub
축소 버전 : (146 바이트)
Sub g(n)
For i=0To 1
For x=-3To 3Step 0.05
y=n^x*Cos(Atn(1)*4*x)
If y<m Then m=y
If i=1Then Cells(500*(1-y/m)+1,(x+3)*100+1)="#"
Next
Next
End Sub
축소 된 버전을 VBA에 복사 / 붙여 넣기하면 자동으로 원본으로 확장됩니다. 공백을 제거하는 것이 유효한 곳에서 놀 수 있습니다. 내가 지금까지 찾은 것은 VBA가 없으면 유효한 코드가 아니기 때문에 VBA가 특정 명령이 나타날 것으로 예상되는 패턴을 따르는 것 같습니다. 여기까지 내가 찾은 것들이 있습니다 :
+-=/*^
등To
및 Step
A의 For
문 :For x=-3To 3Step 0.05
To
, &
, Then
, 등)이 숫자로 리터럴 등의 앞에 않다면, )
, ?
, %
, 등&
문자열을 결합한 후 :Cells(1,1)=Int(t)&Format(t,":hh:mm:ss")
If s=StrReverse(s)Then
Replace(Space(28)," ",0)
?
vs 와 같은 Print
것이 허용되지만 &
변수 eg 직후 에 형식 선언 을하는 것은 예를 들어 Debug.?a&"z"
제공합니다 Debug.Print a&; "z"
. ;
추가 된 문자는 코드를 실행하는 데 필수적입니다. 여전히 허용됩니까?
If i=1 Then
될 수 있습니다 If i=1Then
일반적 리터럴을 다음 예약 된 단어로, 숫자일지도 때문에 )
, ?
, %
, ... 등으로 구분 할 필요가 없습니다 공간
)
(또는 다른 숫자가 아닌 다른 리터럴)과&
픽셀 아트는 이미 캔버스를 만들 필요가 없기 때문에 Excel의 가장 강력한 영역 중 하나입니다. 작은 조정 만하면됩니다.
Cells.RowHeight=48
또는 대안으로 1 바이트 이상이지만 작업하기가 훨씬 쉽습니다.
Cells.ColumnWidth=2
전화를 통해 모든 Range
개체에 색상을 지정할 수 있습니다
`MyRangeObj`.Interior.Color=`ColorValue`
참고 : 이것은이 위키에 언급 된 다른 트릭과 결합 될 수 있으며 , 또는 호출 사용에 대한 []
표기법 (예 :)을 사용하여 범위를 참조하는 등의 방법을 [A1:R5,D6]
사용할 수 있습니다 . 또한,이 위키에서 언급 한 바와 같이, 이것은 음의 색상 값과 결합하여 색상 참조의 크기를 줄입니다.
Cells(r,c)
Range(cellAddress)
범위 기준
셀 A1
은 다음 방법 중 하나로 참조 될 수 있습니다.
Range("A1")
Cells(1,1)
[A1]
Range A1:D4
는 다음 방법 중 하나로 참조 될 수 있습니다.
Range("A1:D4")
Range("A1").Resize(4,4)
Cells(1,1).Resize(4,4)
[A1].Resize(4,4,)
[A1:D4]
색상 참조
Black 0
White -1
Red 255
Aqua -256
특정 기능을 자주 사용하는 경우 사용자 정의 기능에 다시 할당하십시오.
다음 코드 ( 127 자)를 줄일 수 있습니다.
Sub q()
w = 0
x = 1
y = 2
z = 3
a = Format(w, "0.0%")
b = Format(x, "0.0%")
c = Format(y, "0.0%")
d = Format(z, "0.0%")
End Sub
~ ( 124 자) :
Sub q()
w = 0
x = 1
y = 2
z = 3
a = f(w)
b = f(x)
c = f(y)
d = f(z)
End Sub
Function f(g)
f = Format(g, "0.0%")
End Function
이것을 ByRef 트릭 과 결합하면 더 많은 문자를 줄일 수 있습니다 ( 114까지 ) :
Sub q()
w = 0
x = 1
y = 2
z = 3
a = f(w)
b = f(x)
c = f(y)
d = f(z)
End Sub
Sub f(g)
g = Format(g, "0.0%")
End Sub
VBA는를 정의하기 위해 많은 문자를 사용하므로 신중하게 수행하십시오 Function
. 두 번째 코드 블록은 실제와 처음보다 더 큰 것이 어떤 번호를 적은 Format()
전화.
a = f(w)
줄일 수있다f w
입력 변수를 통해 Sub
루틴 및 Function
s에 입력
Public Sub A(ByRef B as String)
로 축소 될 수 있습니다
Sub a(b$)
Public
및 ByRef
호출 VBA 따라서 암시의 기본이며, (거의) 항상 삭제 될 수 있습니다.
형식 리터럴 $
은 b
형식이 String
됩니다.
다른 타입 리터럴
!
단일@
통화#
더블%
정수$
끈&
긴^
LongLong (64 비트 만 해당)또한 일반적으로 입력 변수를 기본 유형으로 Variant
남겨두고 유형 기반 오류를 처리하지 않은 채로 둘 수 있습니다. 예 : Sub E(F)
하는 F
형식이 될 것으로 예상된다 Boolean[]
(같은 루틴에 전달 될 것이다 E Array(True, False, False)
)
다음을 Sub
통해 루틴 및 즉시 창 기능에 입력Cells
VBA에는 완전한 기능을 갖춘 콘솔이 없으므로 공식 STDIN 이 없으므로 입력을 통과 하면서 약간의 플레이가 가능합니다.
엑셀에서, 일반적으로 셀 또는 셀 범위로부터 입력을받는 것이 받아 들여지며, 이는 다음과 같이 수행 될 수있다
s=[A1]
.value
셀에서 암시 적으로 넣습니다 [A1]
( cells(1,1)
또는range("A1")
예제 문제점 : 메시지 상자에 입력 표시
서브 루틴을 통해 Sub A:msgbox[A1]:End Sub
즉시 창 기능을 통해 msgbox[A1]
조건부 컴파일 인수를 통해 입력
VBA 프로젝트는 명령 행 또는 VBAProject 속성을 통한 인수 사용을 지원합니다 (프로젝트 탐색기를 통해보기-> [VBA 프로젝트]-(오른쪽 클릭)-> VBAProject 속성-> 조건부 컴파일 인수).
이것은 에러 코드 챌린지에 매우 유용합니다
조건부 컴파일 인수 n=
[some_value]가 주어지면의 값을 기반으로 오류 코드를 생성하는 코드를 실행할 수 있습니다 n
. n=
VBAProject 속성 창의 조건부 컴파일 인수 섹션에서 코드에 2 바이트를 추가해야합니다 .
예제 코드
...
#If n=3 then
return '' Produces error code '3', Return without GoSub
#ElseIf n=20 then
resume '' Produces error code '20', Resume without Error
#EndIf
...
기능 값을 통한 출력
말할 것도없이, 아래 인용 된 일반적인 형태는 가능한 한 컴팩트합니다.
Public Function A(b)
...
A=C
End Function
참고 : 대부분 의 경우 메소드를 서브 루틴으로 바이트 변환하고 VBE 즉시 창으로 출력하는 것이 더 많습니다 (아래 참조).
VBE 직접 실행 창을 통해 Sub
루틴 및 Function
s 에서 출력
VBE 즉시 실행 창 (일명 VBE 디버그 창)으로 출력하는 것은 텍스트 기반 챌린지에 대한 VBA의 일반적인 출력 방법이지만 Debug.Print "Text"
호출이 실질적으로 진행될 수 있음 을 기억해야합니다 .
Debug.Print "Text"
기능적으로 동일하다
Debug.?"Text"
에 ?
자동 형식으로 Print
.
Sub
다른 방법을 통해 루틴 및 VBE 즉시 실행 창 기능 에서 출력
에 드문 상황이 바로 때 때, 당신은 글꼴 크기 조정, 글꼴 선택으로 VBA 사용할 수있는 더 사소한 입력의 일부에서 입력을하고, 확대 할 수있다. (예 : 단어 글꼴 크기 선택기 에뮬레이션 )
StackExchange이 사용하기 때문에 마크 다운 과 Prettify.js을 일반적으로 그들에게보다 전문적인 보이게 코딩 답변에 언어 플래그를 추가 할 수 있습니다. 이것이 VBA에서 골프를 더 잘하게 할 것이라고 보장 할 수는 없지만, 당신이 당신처럼 보이게 할 것이라고 보장 할 수 있습니다.
아래 플래그 중 하나를 추가하면
Public Sub a(ByRef b As Integer) ' this is a comment
에
Public Sub a(ByRef b As Integer) ' this is a comment
VBA 언어 태그
<!-- language: lang-vb -->
<!-- language-all: lang-vb -->
참고 : 후자는 답변의 모든 코드 세그먼트를 변환하지만 이전 코드는 바로 다음 코드 세그먼트 만 변환합니다.
lang-vb
뭐라고? lang-vba
-VBA 답변 보다 형식이 더 이상 합니다.
lang-vba
는 강조 표시를 제공하지만 실제로 기본 강조 표시 만 제공 하기 때문 입니다. VBA는 실제로 Prettify.js에서 구현되지 않았으므로 VB 강조 표시를 사용해야합니다.
If .. Then
검사다른 언어와 마찬가지로, 여러 If
검사는 보통의 사용을 허용 한 라인으로 결합 할 수 있습니다 And
/ Or
(예 : &&
/ ||
VBA에서 모두 대체, C 등의) Then
과를 End If
.
예를 들어 중첩 된 조건부 ( 93 자)를 사용하는 경우 :
'There are MUCH easier ways to do this check (i.e. a = d).
'This is just for the sake of example.
If a = b Then
If b = c Then
If c = d Then
MsgBox "a is equal to d"
End If
End If
End If
가능 ( 69 자) :
If a = b And b = c And c = d Then
MsgBox "a is equal to d"
End If
중첩되지 않은 조건부에서도 작동합니다.
다음을 고려하십시오 ( 84 자).
If a = b Then
d = 0
End If
If c = b Then
d = 0
End If
이것은 ( 51 문자) 가 될 수 있습니다 :
If a = b Or c = b Then
d = 0
End If
d=iif(a=b or c=b,0,d)
For
루프For
루프를 사용할 때 Next
행에는 변수 이름이 필요하지 않습니다 (일반 코딩에 사용하는 것이 더 나을 수도 있음).
따라서,
For Variable = 1 to 100
'Do stuff
Next Variable
단축 할 수 있습니다 :
For Variable = 1 to 100
'Do stuff
Next
(저축은 변수 이름에 따라 다르지만 골프를 타는 경우 1 자 + 1 자 정도일 것입니다.)
때로는 문자열을 개별 문자로 분리하는 것이 유용 할 수 있지만 VBA에서 수동으로이 작업을 수행하려면 약간의 코드가 필요할 수 있습니다.
ReDim a(1 To Len(s))
' ReDim because Dim can't accept non-Const values (Len(s))
For i = 1 To Len(s)
a(i) = Mid(s, i, 1)
Next
대신, 작업을 완료하기 위해 한 줄의 상대적으로 최소한의 함수 체인을 사용할 수 있습니다.
a = Split(StrConv(s, 64), Chr(0))
이것은 문자열 s
을 Variant
array에 할당합니다 a
. 그러나 배열의 마지막 항목은 빈 문자열 ( ""
)이므로 적절하게 처리해야합니다.
작동 방식은 다음과 같습니다.이 StrConv
함수는 a String
를 다른 형식으로 변환합니다 . 이 경우 64 = vbUnicode
이므로 유니 코드 형식으로 변환됩니다. 간단한 ASCII 문자열을 처리 할 때 결과는 빈 문자열이 아닌 null 문자입니다.""
각 문자 뒤에 삽입 된 아님)입니다.
다음 Split
은 String
null 문자 Chr(0)
를 구분 기호로 사용하여 결과 를 배열로 변환합니다 .
Chr(0)
빈 문자열 ""
과 동일하지 않다는 점에 유의해야 하며 Split
on ""
을 사용 하면 예상 한 배열이 반환되지 않습니다. vbNullString
골프 도 마찬가지 인데, 왜 그런 장황한 상수를 처음에 사용하겠습니까?).
With
(때때로! 참조 각주)사용하여 With
반복적 일부 개체를 사용하여 크게 if 문은 코드의 크기를 줄일 수 있습니다.
즉이 ( 80 문자) :
x = foo.bar.object.a.value
y = foo.bar.object.b.value
z = foo.bar.object.c.value
( 79 자) 로 코딩 할 수 있습니다 :
With foo.bar.object
x = .a.value
y = .b.value
z = .c.value
End With
위의 시나리오는 최고의 시나리오가 아닙니다. Access에서 Application
와 같이 와 함께 무언가를 사용 Excel.Application
하면 개선이 훨씬 더 중요합니다.
* 상황에 따라 With
이보다 더 효율적일 수도 있고 그렇지 않을 수도 있습니다 ( 64 자).
Set i = foo.bar.object
x = i.a.value
y = i.b.value
z = i.c.value
교체를 고려해보다
Do While a<b
'...
Loop
또는
Do Until a=b
'...
Loop
구식이지만 적은 바이트 수
While a<b
'...
Wend
a Sub
또는 Function
조기 에 종료해야하는 경우 대신Exit ...
For i=1To 1000
If i=50 Then Exit Sub
Next
치다 End
For i=1To 1E3
If i=50 Then End
Next
End
모든 코드 실행 을 중지하고 전역 변수를 지우므로 현명하게 사용하십시오.
For
및 End
)을 다시 작성하여 사건 100
이 충족되지 않고 불필요한 바이트를 추가 할 수 있음을 반영해야합니다.
Debug.Print
및 Print
통화Debug.Print [some value]
(12 바이트; 후행 공백에 유의하십시오.)
Debug.?[some value]
(7 바이트; 후행 공간 부족에주의하십시오).
비슷하게,
Print
(6 바이트)는
?
(1 바이트).
또한 익명의 VBE 즉시 창 기능과 관련하여 작업 Debug
할 때 명령문이 완전히 삭제 될 수 있으며 대신 VBE 즉시 창으로 인쇄 ?
하는 것은 STDIN / STDOUT으로 가정 될 수 있습니다.
문자열을 인쇄 할 때 대신 특수 문자를 사용할 수도 있습니다 &
. 이것들은 인쇄되거나 공백 제거되는 대체 형식을 허용합니다
변수 문자열을 결합하는 대신
Debug.Print s1 &s2
세미콜론을 사용할 수 있습니다 ;
Debug.?s1;s2
이 세미콜론은 모호성이없는 한 연속 문자열의 기본 동작입니다.
Debug.?s1"a"
Debug.?"a"s1
하지만
Debug.?s1s2 'as this could be interpreted as a variable named "s1s2", not 2 variables
'use Debug.?s1 s2 instead (or s1;s2)
Debug.?"a""b" 'this prints a"b, so insert a space or ; for ab
참고로; 줄 끝에는 줄 바꿈이 기본적으로 인쇄 될 때마다 추가되므로 줄 바꿈이 표시되지 않습니다. VBA 코드에 의해 반환 된 바이트 수 를 논의 중입니다
탭과 결합하려면 쉼표를 사용하십시오 ,
(실제로 14 칸이지만에 따라).
Debug.?s1,s2 'returns "s1 s2"
마지막으로 형식 선언을 사용하여; 대신 문자열을 조인 할 수 있으며 각각 형식에 약간의 영향을 미칩니다. 아래 a = 3.14159
는 모두 첫 번째 줄입니다.
Debug.?a&"is pi" -> " 3 is pi" 'dims a as long, adds leading and trailing space to a
Debug.?a!"is pi" -> " 3.14159 is pi" 'dims a as single, adds leading and trailing space
Debug.?a$"is pi" -> "3.14159is pi" 'dims a as string, no spaces added
Sub
를 사용 하여Print
코드에서 6 개 이상의 Debug.?
문을 사용해야하는 경우 모든 디버그를 바꾸어 바이트를 줄일 수 있습니다. 아래와 같이 Sub에 대한 호출이있는 회선. 빈 줄을 인쇄하려면 p ""
매개 변수가 필요하므로 전화해야 합니다.
Sub p(m)
Debug.?m
End Sub
p""
경우 또는 종료 할 수없는 경우 p"
. 그러나 이것이 적용될 수있는 대부분의 경우 문자열 변수를 사용하고 끝에 문자열 변수 만 인쇄하는 것이 더 합리적입니다.
Array()
Choose()
Select
If...Then
다른 변수의 값을 기반으로 변수를 할당 할 때 다음과 같이 If...Then
검사로 단계를 작성하는 것이 좋습니다 .
If a = 1 Then
b = "a"
ElseIf a = 2 Then
b = "c"
'...
End If
그러나 확인할 하나 또는 두 개 이상의 변수가있는 경우 많은 코드 공간을 차지할 수 있습니다 (아직 어쨌든 일반적으로 더 나은 방법이 있습니다).
대신,이 Select Case
명령문은 다음과 같이 모든 것을 하나의 블록으로 묶어 검사 크기를 줄이는 데 도움이됩니다.
Select Case a
Case 1:
b = "a"
Case 2:
b = "c"
'...
End Select
이것은 훨씬 작은 코드로 이어질 수 있지만 이와 같은 매우 간단한 경우에는 훨씬 더 효율적인 방법 Choose()
이 있습니다 . 이 함수는 전달 된 값을 기반으로 목록에서 값을 선택합니다.
b = Choose(a,"a","c",...)
선택하는 옵션 ( a
이 경우)은 첫 번째 인수로 전달 된 정수 값입니다. 이후의 모든 인수는 선택할 수있는 값입니다 (대부분의 VBA와 마찬가지로 1- 색인). 값은 설정중인 변수와 일치하는 한 (즉, Set
키워드 없이 객체가 작동하지 않는) 데이터 유형일 수 있으며 표현식 또는 함수일 수도 있습니다.
b = Choose(a, 5 + 4, String(7,"?"))
추가 옵션은이 Array
기능 을 사용하여 다른 캐릭터를 저장하는 동안 동일한 효과를 얻는 것입니다.
b = Array(5 + 4, String(7,"?"))(a)
IIf()
다른 것과 함께 사용하는 것입니다 Choose()
.A1=IIf(a=Choose(b,c,d,e),Choose(Choose(f,g,h,i),j,k,l),Choose(IIf(m=n,Choose(p,q,r,s),IIf(t=u,v,w)),x,y,z))
Excel에서 색상 (부호없는 6 자 16 진 정수)을 처리하는 방식으로 음의 부호가있는 정수를 사용할 수 있습니다.이 중 Excel에서는 오른쪽 6 바이트 만 사용하여 색상 값을 지정합니다.
이것은 약간 혼란 스러우므로 몇 가지 예가 아래에 제공됩니다.
흰색으로 저장된 흰색을 사용한다고 가정 해 보겠습니다.
rgbWhite
그리고
&HFFFFFF ''#value: 16777215
골프에 우리가해야 할 모든 다운이는 찾을 수 있습니다 부정의 에 종료 16 진수 값 FFFFFF
의 형식이어야에 부정적인 진수 값과 이후 FFFFXXXXXX
(즉, 같은 X
에서 카운트 다운 유효한 16 진수입니다) FFFFFFFFFF
( -1
을)를 FFFF000001
( -16777215
)
이것을 알면 공식을 일반화 할 수 있습니다
Let Negative_Color_Value = -rgbWhite + Positive_Color_Value - 1
= -16777215 + Positive_Color_Value - 1
= -16777216 + Positive_Color_Value
이것을 사용하면 유용한 전환이 있습니다.
rgbWhite = &HFFFFFF = -1
rgbAqua = &HFFFF00 = -256
16747627 = &HFF8C6B = -29589
rgbWhite
= 2^24-1
-1을 놓치면 더 줄어들 수 있습니다
&000080: 2^7, &000100: 2^8, &000200: 2^9, &000400: 2^10, &000800: 2^11, &001000: 2^12, &002000: 2^13, &004000: 2^14, &008000: 2^15, &010000: 2^16, &01FFFF: 2^17-1, &020000: 2^17, &03FFFF: 2^18-1, &040000: 2^18, &07FFFF: 2^19-1, &080000: 2^19, &0FFFFF: 2^20-1, &100000: 2^20, &1FFFFF: 2^21-1, &3FFFFF: 2^22-1, &400000: 2^22, &7FFFFF: 2^23-1
nb 반드시 완료 할 필요는 없지만 상당히 철저한 작업을 수행 한 것 같습니다
"
창으로 인쇄시 터미널 생략디버그 창에서 사용될 아래 기능이 주어지면
h="Hello":?h", World!"
터미널 "
은 -1 바이트 동안 삭제 될 수 있으며, 문자열은 닫히지 않고 프로그램은 오류없이 동일하게 실행됩니다.
h="Hello":?h", World!
이것보다 더 놀라운 것은 이것이 완전히 정의 된 서브 루틴 내에서 수행 될 수 있다는 것입니다.
Sub a
h="Hello":Debug.?h", World!
End Sub
위의 서브 루틴은 예상대로 실행되고
Sub a()
h = "Hello": Debug.Print h; ", World!"
End Sub
직접에 숫자 유형을 사용하여 - 때로는 암시 적 형식 변환이라고 If
, [IF(...)]
또는IIf(...)
문, 그 수 할 수있는 절대적으로 저장 일부 바이트 truthy 및 falsey 특성을 사용하여.
VBA에서 0이 아닌 모든 숫자 유형 변수는 진실한 것으로 간주되므로 (0 0
은 유일한 값은 거짓입니다)
If B <> 0 Then
Let C = B
Else
Let C = D
End If
응축 될 수 있습니다
If B Then C=B Else C=D
그리고 더
C=IIf(B,B,D)
LongLong
64 비트 VBA의 지수 및 s지수의 일반적인 형태
A to the power of B
VBA 에서처럼
A^B
그러나 32 비트 Office 설치에서만 , 64 비트 Office 설치에서는 오류없이 나타낼 수있는 가장 짧은 방법은 다음과 같습니다.
A ^B
이는 64 비트 버전의 VBA ^
에서 지수 리터럴과 LongLong
형식 선언 문자 로 사용되기 때문입니다 . 이것은 다소 이상하게 보이지만 유효한 구문이 발생할 수 있음을 의미합니다.
a^=2^^63^-1^
변수 a
의 최대 값을 보유하도록 변수 를 할당합니다 .Longlong
솔루션에 일정한 데이터를 유지해야하는 칼랑의 경우 해당 데이터를 단일 문자열로 압축 한 다음 문자열을 반복하여 데이터를 가져 오는 것이 유용 할 수 있습니다.
VBA에서 모든 바이트 값은 다음과 같은 문자로 직접 변환 될 수 있습니다.
Chr(byteVal)
그리고 a long
또는 integer
value는 다음 두 문자로 변환 될 수 있습니다.
Chr(longVal / 256) & Chr(longVal Mod 256)
따라서 byte
배열의 압축 알고리즘은 다음과 같습니다.
For Each Var In bytes
Select Case Var
Case Is = Asc(vbNullChar)
outstr$ = outstr$ & """+chr(0)+"""
Case Is = Asc(vbTab)
outstr$ = outstr$ & """+vbTab+"""
Case Is = Asc("""")
outstr$ = outstr$ & """"""
Case Is = Asc(vbLf)
outstr$ = outstr$ & """+vbLf+"""
Case Is = Asc(vbCr)
outstr$ = outstr$ & """+vbCr+"""
Case Else
outstr$ = outstr$ & Chr$(Var)
End Select
Next
Debug.Print "t="""; outstr$
Select Case
문자열에 리터럴로 저장 될 수없는 문자로 인해 섹션이 구현 된다는 점에 유의하십시오 .
결과 문자열에서 다음과 같이 보입니다.
t="5¼-™):ó™ˆ"+vbTab+"»‘v¶<®Xn³"+Chr(0)+"~ίšÐ‘š;$ÔÝ•óŽ¡¡EˆõW'«¡*{ú{Óx.OÒ/R)°@¯ˆ”'®ïQ*<¹çu¶àªp~ÅP>‹:<«a°;!¾y›/,”Ì#¥œ5*B)·7
그런 다음 Asc
및 Mid
기능을 사용하여 데이터를 추출 할 수 있습니다.
i=Asc(Mid(t,n+1))
경우에 따라 VBA를 사용하면 상수 값이 필요한 표현식에 나열되지 않거나 부적절한 상수를 사용할 수 있습니다. 이들은 종종 레거시 값이며 적절한 값보다 길이가 짧습니다.
예를 들어 아래 값은 rng.HorizantalAlignment
속성에 의해 값을 유지하게 할 때 사용될 수 있습니다 .
예를 들어 셀의 텍스트가 중앙에 위치하도록 설정하는 것은
rng.HorizantalAlignment=-4108
로 단축 될 수 있습니다
rng.HorizantalAlignment=3
3
적절한 값으로 부적절한 상수 값 을 대체하여 -4108
. rng.HorizantalAlignment
속성 값 을 가져 오면 적절한 값이 반환됩니다. 이 경우에는입니다 -4108
.