[vba]CAD도면 작성-문자열 쓰기(DXF)

도면파일(DXF 파일)에 내가 원하는 문자열을 쓰기

작성의도 : 도면 작성 자동화

Sub WriteDXFText(FileNumber As Integer, myText As String, Layer As String, x As Double, y As Double, z As Double, TextHeight As Double, Color As Integer, Optional Style As String = "Standard")
    '
    'How to use this subprocedure:
    'WriteDXFText(FileNumber , "my  story goes here.", "0", 10, 15, 0, 3, 1)
    
    '"Text" entity
    Print #FileNumber, Format(0, "@@@")
    Print #FileNumber, "TEXT"
    '
    Print #FileNumber, Format(1, "@@@")
    Print #FileNumber, myText
    '
    'Style Name
    Print #FileNumber, Format(7, "@@@")
    Print #FileNumber, Style
    '
    'Layer Name
    Print #FileNumber, Format(8, "@@@")
    Print #FileNumber, Layer
    '
    '
    'x coordinate of start point
    Print #FileNumber, Format(10, "@@@")
    Print #FileNumber, x
    '
    'y coordinate of start point
    Print #FileNumber, Format(20, "@@@")
    Print #FileNumber, y
    '
    'z coordinate of start point
    Print #FileNumber, Format(30, "@@@")
    Print #FileNumber, z
    '
    'Text Height
    Print #FileNumber, Format(40, "@@@")
    Print #FileNumber, TextHeight
    '
    'Text Color
    Print #FileNumber, Format(62, "@@@")
    Print #FileNumber, Color
    '
End Sub

[vba]Format Function

[문제]
변수를 사용자가 원하는 형식으로 문자열로 출력하기

[설명]
User-Defined String Formats (Format Function) You can use any of the following characters to create a format expression for strings:

Excerpted and translated from Format Function (Visual Basic for Applications)

Character Description
@ 문자 표시자. 문자를 표시하거나, 아니면 공백을 표시한다. 문자열 중에서 골뱅이 ( @ )가 나타나는 위치에 문자가 있으면, 그 문자를 표시한다. 그렇지 않으면 그 자리에 공백을 표시한다. 문자표시자를 우측부터 좌측으로 채워진다. 다만, 느낌표( ! )가 있으면, 좌측부터 우측으로 채운다.
&; 문자 표시자. 문자를 표시하거나, 아니면 아무것도 표시하지 않는다. 문자열 중에서 앰퍼샌드ampersand ( &; )가 나타나는 위치에 문자가 있으면, 그 문자를 표시한다. 그렇지 않으면, 아무 것도 표시하지 않는다. 문자표시자를 우측부터 좌측으로 채워진다. 다만, 느낌표( ! )가 있으면, 좌측부터 우측으로 채운다.
< 소문자로 표시. 모든 문자를 소문자로 표시한다.
> 대문자로 표시. 모든 문자를 대문자로 표시한다.
! 문자표시자의 좌측부터 문자를 채움. 기본은 문자표시자의 우측부터 채운다.

[예제]
세 칸 안에 숫자를 출력한다. 해당 자리에 숫자가 없으면 빈칸으로 처리한다. 오른쪽 정렬로 표시한다.

Print #FileNumber, Format(0, "@@@")
Print #FileNumber, "LINE"
Print #FileNumber, Format(99, "@@@")
Print #FileNumber, Format(999, "@@@")
Print #FileNumber, Format(5459.4, "##,##0.00")
Print #FileNumber, Format(334.9, "###0.00")
Print #FileNumber, Format(5, "0.00%")
Print #FileNumber, Format("HELLO", "<")
Print #FileNumber, Format("This is it", ">")

위 예제의 출력 결과는 다음과 같다.

  0
LINE
 99
999
5,459.40
334.90
500.00%
hello
THIS IS IT

[FYI]
String.Format Method

[vba] CAD도면 작성 – Line 그리기(DXF)

DXF를 사용하면 고품질의 CAD 파일을 출력할 수 있다. 즉 VBA를 통하여 자동으로 도면을 그릴 수 있다. DXF는 AutoCAD와 호환이 되도록 설계된 파일형식이다.

작성의도 : 도면 작성 자동화

아래의 코드는 여기에 있는 DXF파일을 출력하는 코드이다.

Sub WriteDXFFileTest()
    Dim fileNum As Integer
    Dim fileName As String
    '
    fileNum = FreeFile
    fileName = "C:\DXFTest.dxf"
    '
    Open fileName For Output As #fileNum
    '
    Print #fileNum, Format(999, "@@@")
    Print #fileNum, "Created by SolarView"
    '
    Print #fileNum, Format(0, "@@@")
    Print #fileNum, "SECTION"
    '
    Print #fileNum, Format(2, "@@@")
    Print #fileNum, "ENTITIES"
    '
    Call WriteDXFLine(fileNum, 0, 4, 12.5, 13.5, 0, 100.7, 101.7, 0)
    '
    Print #fileNum, Format(0, "@@@")
    Print #fileNum, "ENDSEC"
    '
    Print #fileNum, Format(0, "@@@")
    Print #fileNum, "EOF"
    '
    Close #fileNum
    '
End Sub

LINE명령어를 처리하는 함수는 다음과 같이 작성할 수 있다.

Sub WriteDXFLine(FileNumber As Integer, Layer As String, Color As Integer, _
                 X1 As Double, Y1 As Double, Z1 As Double, _
                 X2 As Double, Y2 As Double, Z2 As Double)
    '
    '"Line" entity
    Print #FileNumber, Format(0, "@@@")
    Print #FileNumber, "LINE"
    '
    'Layer Name
    Print #FileNumber, Format(8, "@@@")
    Print #FileNumber, Layer
    '
    'Line Color
    Print #FileNumber, Format(62, "@@@")
    Print #FileNumber, Color
    '
    'x coordinate of start point
    Print #FileNumber, Format(10, "@@@")
    Print #FileNumber, X1
    '
    'y coordinate of start point
    Print #FileNumber, Format(20, "@@@")
    Print #FileNumber, Y1
    '
    'z coordinate of start point
    Print #FileNumber, Format(30, "@@@")
    Print #FileNumber, Z1
    '
    'x coordinate of end point
    Print #FileNumber, Format(11, "@@@")
    Print #FileNumber, X2
    '
    'y coordinate of end point
    Print #FileNumber, Format(21, "@@@")
    Print #FileNumber, Y2
    '
    'z coordinate of end point
    Print #FileNumber, Format(31, "@@@")
    Print #FileNumber, Z2
    '
End Sub

이와 같은 요령으로 AutoCAD의 line뿐만 아니라 circle, arc, pline 등 모든 도면 요소(drawing entities)를 그릴 수 있다.

[VBA] VBA Functions for Excel

VBA Function역할
Abs숫자의 절대값을 반환한다.
Array배열을 담고 있는 variant를 반환한다.
Asc문자열의 첫 글자의 ASCII 값을 반환한다.
Atn숫자의 아크탄젠트(arctangent) 값을 반환한다.
CBool부울(boolean) 형식으로 변환한다.
CByte바이트(byte) 형식으로 변환한다.
CCur(currency)형식으로 변환한다.
CDateConverts an expression to date data type
CDblConverts an expression to double data type
CDecConverts an expression to decimal data type
ChooseSelects and returns a value from a list of arguments
ChrConverts an ANSI value to a string
CIntConverts an expression to integer data type
CLngConverts an expression to long data type
CosReturns the cosine of a number
CreateObjectCreates an OLE Automation object
CSngConverts an expression to single data type
CStrConverts an expression to string data type
CurDirReturns the current path
CVarConverts an expression to variant data type
CVDateConverts an expression to date data type
CVErrReturns a user-defined error number
DateReturns the current system date
DateAddReturns a date with a specific date interval added to it
DateDiffReturns a date with a specific date interval subtracted from it
DatePartReturns an integer containing a specific part of a date
DateSerialConverts a date to a serial number
DateValueConverts a string to date
DayReturns the day of the month of a date
DirReturns the name of a file or directory that matches a pattern
DoEventsYields execution so the operating system can process other events
EOFReturns True if the end of a text file has been reached
ErrorReturns the error message that corresponds to an error number
ExpReturns the base of the natural logarithms (e) raised to a power
FileAttrReturns the file mode for a text file
FileDateTimeReturns the date and time when a file was last modified
FileLenReturns the number of bytes in a file
FixReturns the integer portion of a number
FormatDisplays an expression in a particular format
Format CurrencyReturns a number as a string, formatted as currency
FormatDateTimeReturns a number as a string, formatted as a date and/or time
Format NumberReturns a number as a formatted string
Format PercentReturns a number as a string, formatted as a percentage
FreeFileReturns the next file number available for use by the Open statement
GetAllReturns a list of key settings and their values (originally created with SaveSetting) from an application’s entry in the Windows registry
GetAttrReturns a code representing a file attribute
GetObjectRetrieves an OLE Automation object from a file
GetSettingReturns a key setting value from an application’s entry in the Windows registry
HexConverts from decimal to hexadecimal
HourReturns the hour of a time
IIfReturns one of two parts, depending on the evaluation of an expression
InputReturns a specific number of characters from an open text file
InputBoxDisplays a box to prompt a user for input
InStrReturns the position of a string within another string
InStrRevReturns the position of a string within another string, beginning at the back end of the string
IntReturns the integer portion of a number
IsArrayReturns True if a variable is an array
IsDateReturns True if a variable is a date
IsEmptyReturns True if a variable has been initialized
IsErrorReturns True if an expression is an error value
IsMissingReturns True if an optional argument was not passed to a Procedure
IsNullReturns True if an expression contains no valid data
IsNumericReturns True if an expression can be evaluated as a number
IsObjectReturns True if an expression references an OLE Automation object
JoinReturns a string created by joining a number of substrings contained in an array
LBoundReturns the lower bound of an array
LCaseReturns a string converted to lowercase
LeftReturns a specified number of characters from the left of a string
LenReturns the length of a string, in characters
LocReturns the current read or write position of a text file
LOFReturns the number of bytes in an open text file
LogReturns the natural logarithm of a number
LTrimReturns a copy of a string with no leading spaces
MidReturns a specified number of characters from a string
MidBReturns a specified number of bytes from a string
MinuteReturns the minute of a time
MonthReturns the month of a date
MonthNameReturns a string indicating the specified month
MsgBoxDisplays a modal message box
NowReturns the current system date and time
OctConverts from decimal to octal
ReplaceReturns a string in which one substring is replaced with another
RGBReturns a number representing an RGB color value
SpaceReturns a string with a specified number of spaces
SplitReturns an array consisting of a number of substrings
SqrReturns the square root of a number
StrReturns a string representation of a number
RightReturns a specified number of characters from the right of a string
RndReturns a random number between 0 and 1
RoundRounds a number to a specific number of decimal places
RTrimReturns a copy of a string with no trailing spaces
SecondReturns the second of a time
SeekReturns the current position in a text file
SgnReturns an integer that indicates the sign of a number
ShellRuns an executable program
SinReturns the sin of a number
StrCompReturns a value indicating the result of a string comparison
StrConvReturns a string variant converted as specified
StringReturns a repeating character or string
StrReverseReverses the character order of a string
SwitchEvaluates a list of expressions and returns a value associated with the first expression in the list that is True
TabPositions output in an output stream
TanReturns the tangent of a number
TimeReturns the current system time
TimerReturns the number of seconds since midnight
TimeSerialReturns the time for a specified hour, minute, and second
TimeValueConverts a string to a time serial number
TrimReturns a string containing a copy of a specified string without leading spaces and trailing spaces
TypeNameReturns a string that describes the data type of a variable
UBoundReturns the upper bound of an array
UCaseConverts a string to uppercase
ValReturns the numbers contained in a string
VarTypeReturns a value indicating the subtype of a variable
WeekdayReturns a number representing a day of the week
Weekday NameReturns a string indicating the specified weekday
YearReturns the year of a date

[Excel]Solver 활용

[Solver의 원리]
1. Solver Uses Generalized Reduced Gradient Algorithm
2. Design and Use of the Microsoft Excel Solver

 

[Solver의 사용법]
솔버는 여러 가지 용도로 사용할 수 있다. 다음은 여러 영역에서 솔버를 사용한 예이다.
0. https://support.office.com/ko-kr/article/%ED%95%B4-%EC%B0%BE%EA%B8%B0%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EB%AC%B8%EC%A0%9C-%EC%A0%95%EC%9D%98-%EB%B0%8F-%ED%92%80%EA%B8%B0-9ed03c9f-7caf-4d99-bb6d-078f96d1652c
1. Microsoft Excel Solver add-in Examples
2. Quantitative Approaches for Decision Making

 

[VBA 활용]
VBA를 이용해서 직접 솔버를 호출해서 사용할 수도 있다.
1. Creating Visual Basic Macros that Use Microsoft Excel Solver

[VBA]내 코드에서 엑셀 함수를 불러 사용하는 방법

엑셀 함수(정확히는 워크시트 함수)에는 분야별로 많은 함수들이 내장되어 있다. 통계, 공학, 재무, 수학/삼각, 논리 등등 많이 있다. 이것을 내 VBA코드에서 활용할 방법은 없을까?

1) VBA 코드 안에서 풍부한 워크시트 함수를 호출하는 방법
[vb]Application.WorksheetFunction.워크시트함수명(범위)[/vb]

2) A열 전체 중에서 가장 큰 값을 B1에 읽어오기
[vb]Range(“B1”)= Application.WorksheetFunction.Max(Range(“A:A”))[/vb]

3) A열 전체 중에서 가장 큰 값을 가진 셀을 활성화하기
[vb]Range(“A:A”).Find(Application.WorksheetFunction.Max(Range(“A:A”))).Activate[/vb]

[VBA]방정식을 반복법으로 풀기

 e^x - 5 sin x + 1.36 x =0을 반복법으로 풀어라.

먼저, 주어진 식을  x =  g (x)형식으로 변형시킨다.

즉,  x = e^x - 5 sin x + 2.36 x 으로 변형시킨다. 따라서  g(x) = e^x - 5 sin x + 2.36 x 가 된다.

Option Explicit

'허용오차(allowable error)
Private Const EPS As Double = 0.00001 'epsilon의 약자. 매우 작은 값 그러나 0은 아니다.
'which stands for epsilon, mean very small but nonzero

Sub SolveEquation()
  Dim x0 As Double
  Dim x1 As Double
  '
  '
  '1) 초기값 x0를 적당히 정한다.
  x0 = Range("A3")
  '2) x1 = G(x0)를 계산한다.
  x1 = G(x0)
  '
  Do Until (Abs(x1 - x0) < EPS) '수렴할 때까지 계산해라.
    x0 = x1 '//새로 계산한 값(x1)을 이전 값(x0)으로 대체한다.
    x1 = G(x0) '//다시 새로운 값(x1)을 계산한다.
  Loop
  '
  '
  Range("C3") = x1
End Sub

풀어야 할 방정식은 다음과 같다.

Function G(x As Double) As Double
' 계산할 방정식 f(x) = 0 를 x = g(x) 형식으로 변환시킨 것
  G = Exp(x) - 5 * Sin(x) + 2.36 * x
End Function

[VBA] vector operation

벡터 계산을 위한 구조체 선언

Option Explicit

Type Vector3D '3차원 벡터를 위한 자료 구조
  X As Double
  Y As Double
  Z As Double
End Type

내적 계산하기

Function DotProduct(v1 As Vector3D, v2 As Vector3D) As Double
DotProduct = v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z
End Function

벡터의 합

Function VectorAddition(v1 As Vector3D, v2 As Vector3D) As Vector3D
Dim c As Vector3D
'
c.X = v1.X + v2.X
c.Y = v1.Y + v2.Y
c.Z = v1.Z + v2.Z
'
VectorAddition = c
End Function

외적

Function CrossProduct(v1 As Vector3D, v2 As Vector3D) As Vector3D
Dim c As Vector3D
'
c.X = v1.Y * v2.Z - v1.Z * v2.Y
c.Y = v1.Z * v2.X - v1.X * v2.Z
c.Z = v1.X * v2.Y - v1.Y * v2.X
'
CrossProduct = c
End Function

벡터의 크기

Function Norm(v1 As Vector3D) As Double
Norm = Sqr(v1.X * v1.X + v1.Y * v1.Y + v1.Z * v1.Z)
End Function

벡터의 차를 위한 함수

Function MinusVector(v1 As Vector3D) As Vector3D
Dim r As Vector3D
'
r.X = -v1.X
r.Y = -v1.Y
r.Z = -v1.Z
'
MinusVector = r
End Function

벡터의 비교

Function Equals(v1 As Vector3D, v2 As Vector3D) As Boolean
If (v1.X = v2.X And v1.Y = v2.Y And v1.Z = v2.Z) Then
Equals = True
Else
Equals = False
End If
End Function

[VBA]데이터 형식

모든 프로그래밍 언어에는 자신들만의 데이터 형식을 갖고 있다.

다음은 엑셀의 도움말에 있는 내용이다.

데이터 형식저장 용량범위
Byte1바이트0부터 255까지
Boolean2바이트True 또는 False
Integer 2바이트-32,768부터 32,767까지
Long
(긴 정수)
4바이트-2,147,483,648부터 2,147,483,647까지
Single
(단정도 부동 소수점)
4바이트-3.402823E38부터 -1.401298E-45까지(음수값). 1.401298E-45부터 3.402823E38까지(양수값)
Double
(배정도 부동 소수점)
8바이트-1.79769313486232E308부터
-4.94065645841247E-324까지(음수값). 4.94065645841247E-324부터 1.79769313486232E308까지(양수값)
Currency
(정수 값 잘림)
8바이트-922,337,203,685,477.5808부터 922,337,203,685,477.5807까지
Decimal14바이트+/-79,228,162,514,264,337,593,543,950,335(소수점 이하 없음);
+/-7.9228162514264337593543950335(숫자의 오른쪽으로부터 28번째); +/-0.0000000000000000000000000001(0이 아닌 최소 숫자)
Date8바이트100년 1월 1일부터 9999년 10월 31까지
Object4바이트모든 개체 참조
String
(가변 길이)
10바이트 +문자열 길이0부터 약 20억까지
String
(고정 길이)
문자열 길이1부터 약 65,400까지
Variant
(숫자)
16바이트Double형 범위 내의 모든 숫자
Variant
(문자)
22바이트 + 문자열 길이변수 길이 String과 같은 범위
사용자 정의 형식
(Type 사용)
요소가 사용하는 숫자해당 데이터 형식의 범위값과 각 요소의 범위값이 같음

메모 모든 데이터 형식의 배열은 20바이트 + 각 차원당 4바이트 + 데이터 자체가 차지하는 바이트 만큼의 메모리를 차지하며, 각 항목의 수에 항목의 크기를 곱하면 데이터가 차지하는 메모리의 용량을 구할 수 있습니다. 예를 들면 2바이트를 차지하는 4개의 Integer 데이터 요소로 된 1차원 배열은 8바이트를 차지합니다. 데이터의 8바이트와 오버헤드 24바이트를 더하면 배열에 필요한 메모리 양은 32바이트가 됩니다.

Variant는 배열 자체보다 12바이트를 더 차지하는 배열을 가지고 있습니다.

메모 StrConv 함수는 문자열 데이터를 다른 형식의 문자열 데이터로 변환할 때 사용된다.

도움말 끝

<개인 생각>

개인적으로 실수는 Double을, 엑셀의 셀을 참조하기 위한 행, 열 관련 변수는 Long으로 하는 것이 좋다.