한국어 | English
2019년 원본 스크립트 10개를 전수 검토한 결과와, 이번 정리에서 무엇을 어떻게 고쳤는지 기록한다. "왜 이렇게 바꿨는가" 를 남기는 것이 목적이므로 결함마다 원본 코드를 함께 인용한다.
원본은 git log --follow <파일> 로 확인할 수 있다.
Function DateFormateCustom(vTempInputDate, vTempStandard)
...
DateCustom = vTempYear & vTempStandard & vTempMonth & vTempStandard & vTempDay
End FunctionVBScript 는 함수명과 같은 이름의 변수에 대입해야 반환값이 된다. DateCustom 은
함수명(DateFormateCustom)과 다르므로 그냥 지역 변수 하나가 만들어졌다 사라질 뿐이고,
호출자는 항상 빈 값을 받는다. Option Explicit 이 없어 오타가 조용히 통과했다.
같은 파일에 결함이 2개 더 있었다.
If InStr(vTempDateString, "/") <> 0 Then ' 파라미터는 vTempInputDate 다
vTempSplit = "/"
ElseIf InStr(vTempDateString, "-") <> 0 Then
vTempSplit = "_" ' "-" 를 찾고 "_" 로 자른다vTempDateString은 어디에도 없는 변수 → 항상 Empty → 세 조건 모두 거짓 →vTempSplit이 빈 문자열 →Split(값, "")는 원본 전체를 원소 1개로 돌려준다. 결국 월/일/연 분해 자체가 성립하지 않았다.-구분자를 만나면_로 자르도록 되어 있었다(오타).
수정: FormatCustomDate 로 개명하고 반환 대입을 함수명과 일치시킴, 구분자 판정을
DetectDelimiter 로 분리, h:m:s 꼬리 제거, 월/일 zero-pad, 2자리 연도 보정,
파싱 실패 시 예외 대신 빈 문자열 반환.
Dim vIP, vLanguage, vUserName, vPassWord, ...
vPw = WScript.Arguments.Item(3) ' vPw 에 받고
...
vSession.findById(".../pwdRSYST-BCODE").text = vPassWord ' vPassWord 를 쓴다인자를 vPw 에 담고 화면에는 한 번도 대입된 적 없는 vPassWord 를 넣었다. 늘 빈 값이
전송된다. 여기서도 Option Explicit 부재가 원인이다.
vSession.findById("wnd[0]").maximizea ' maximize 오타수정: 변수 통일, maximize 로 정정, Option Explicit 추가.
WScript.StdOut.WriteLine(vMaxRow)
Err.Source 6 ' Err.Source 는 프로퍼티다. 이런 호출 구문은 없다
WScript.StdOut.WriteLine("Fail") ' 조건 없이 실행된다
Err.ClearIf Err.Number <> 0 Then 을 의도한 것으로 보이지만, 실제로는 행 수를 출력한 직후
무조건 Fail 을 한 줄 더 출력한다. 최상단 On Error Resume Next 덕분에 Err.Source 6
자체의 오류도 삼켜져서 아무도 눈치채지 못한다.
수정: 블랭킷 On Error Resume Next 제거, 표준출력에는 행 수만, 실패는 표준오류 +
종료코드(1~4)로 분리.
Function setValue(vTempSheet, vTempColun, vTempMaxRow, vTempSupplier)
vTempRow = 2
Do
vTempSheet.Cells(vTempRow, vTempCol).Value = vTempSupplier
vTempRow = vTempRow + 1
vTempMaxRow = vTempMaxRow - 1
Loop While vTempMaxRow <> 0
End FunctionDo ... Loop While 은 후위 판정이라 최소 1회는 실행된다. vTempMaxRow 가 0 으로
들어오면 1회 쓴 뒤 −1 이 되고, 조건 <> 0 은 영원히 참이다. 데이터가 없는 시트를 만나면
Excel 의 행이 소진될 때까지 셀을 쓴다.
수정: Do While 전위 판정으로 전환하고 RowCount < 1 을 조기 반환. 겸사겸사
셀 단위 COM 호출 루프를 Range(...).Value 한 번의 대입으로 교체했다(수천 행에서 체감 차이가 크다).
파일이 BOM 없는 UTF-8 로 저장되어 있었다. cscript.exe 는 .vbs 를 시스템 코드
페이지(한국어 Windows = CP949)로 읽으므로 "플랜트", "납품처", "생산버전" 리터럴이
모두 깨진다. Range.Find 는 아무것도 못 찾고 FindColume 이 0 을 돌려주며, Cells(row, 0)
접근에서 실패한다.
수정: 작업트리 인코딩을 UTF-16LE + BOM 으로 고정(.gitattributes 의
working-tree-encoding). 저장소 blob 은 UTF-8 이라 GitHub 에서 그대로 읽히고 diff 도 된다.
vExcelPath = WScript.Arguments.Item(0) ' 전체 경로
Set objWorkbook = objexcel.Workbooks(vExcelPath)Workbooks 컬렉션은 파일명으로 색인된다. 전체 경로를 넘기면 항상 실패한다.
수정: 경로를 받아도 leaf 만 잘라 조회하고, 못 찾으면 종료코드 3 으로 명확히 실패.
'vExcelPath = WScript.Arguments.Item(0)
...
Set objWorkbook = objExcel.Workbooks.Open(vExcelPath) ' 빈 값으로 Open수정: 인자 파싱 복원 + 존재 확인 + 사용법/종료코드 추가. 확장자 .vbs 부여.
Set objFileToWrite = CreateObject(“Scripting.FileSystemObject”)...
워드프로세서를 거친 메모가 그대로 커밋되어 따옴표가 U+201C/U+201D, 주석 기호가
U+2018 이었다. 붙여넣는 순간 구문 오류가 난다.
수정: FileLog.vbs 로 실제 동작하는 코드로 재작성. 상수(FOR_APPENDING 등)를 선언하고
(VBA 와 달리 VBScript 에는 내장되어 있지 않다), 빈 파일에서 ReadAll 이 예외를 던지는
문제도 막았다.
For Each x In Split(vTempString, vTempStandard)
If InStr(vCopyString, x) <> 0 Then
vTempStringOne = vTempStringOne & "," & x
vCopyString = Replace(vCopyString, x, "")주석의 예시("a,a,c,c,...")처럼 한 글자 토큰에서만 맞는다. InStr/Replace 는
부분 문자열로 동작하므로 "1000,1010" 같은 코드값에서는 1000 을 지울 때 1010 의 일부까지
훼손된다. 결과 조인도 파라미터 vTempStandard 가 아니라 , 를 하드코딩했다.
수정: Scripting.Dictionary 로 토큰 단위 정확 매칭(vbTextCompare), 구분자는 파라미터 사용.
If vFSO.FolderExists(vFolderPath) Then
Else
Msgbox(vFolderPath) ' 아무도 없는 PC 에서 영원히 대기
vFSO.CreateFolder vFolderPath
End If.bat 으로 스케줄 실행되는 스크립트인데 모달 대화상자를 띄운다. 응답하는 사람이 없으면
백업이 그대로 멈춘다. 그 밖에:
vFolderPath = "C:\"뒤에& "\" &→C:\\2019_7_5(백슬래시 중복)- 월/일 zero-pad 없음 →
2019_10_1이2019_2_1보다 앞에 정렬됨 C:\Users\powergen\...하드코딩,C:\루트 쓰기(관리자 권한 필요)If ... Then Else빈 Then 분기
수정: BackupFolder.vbs 로 개명, MsgBox 제거, 경로를 인자로, BuildPath 사용,
zero-pad, Folder.Copy 대상에 후행 \ 를 붙여 "안으로 복사" 의미를 명확히 함.
| 항목 | 원본 | 수정 |
|---|---|---|
Option Explicit |
전 파일 없음 → 1-1·1-2 결함의 직접 원인 | 전 파일 선언 |
| 미선언 변수 | vCount, vFolderPath, FoundCell, table, row, x … |
전부 Dim |
반환값 없는 Function |
MultiInput, setValue |
Sub 로 전환 |
| 전역 결합 | SapTableInput 이 전역 session 을 가정 |
vSession 파라미터 |
| 오류 처리 | 블랭킷 On Error Resume Next 또는 없음 |
실패 지점별 종료코드 + 표준오류 |
| 무한 대기 | SAP 연결 3개 루프에 타임아웃 없음 | MAX_ATTEMPTS 60회(30초) |
| 파일명 | DateFormateCustom(오타), 확장자 없는 2개, 공백 포함 log write |
정정·.vbs 부여 |
| 비밀번호 | 명령행 인자 | 환경변수 / PSCredential |
Call VerticalScrolling(tempTwo, vCount)
Set table = session.findById(tempTwo)
Set row = table.getcell(1, 1) ' 0-based 인데 1,1GuiTableControl.GetCell(row, column) 은 0 기반이고 스크롤 후의 화면에 보이는 영역을
가리킨다. 한 행씩 스크롤하면서 매번 (1, 1) 을 쓰면 첫 보이는 행을 건너뛰고 두 번째 행에
쓰게 된다. (0, columnIndex) 로 바로잡고 컬럼을 파라미터화했다.
스크롤 직후 findById 로 컨트롤을 다시 얻는 원본 동작은 옳다 — SAP GUI 는 뷰포트가 움직이면
자식 요소를 재생성하므로 이전 참조는 무효가 된다. 주석으로 이유를 명시해 두었다.
- 런타임 검증 불가: 이 정리는 정적 리뷰다. SAP GUI·Excel COM 은 Windows 실환경이
필요하므로 실제 실행 검증은 하지 못했다. 특히 §1-5(인코딩)와
SapTableInput의 0-based 인덱스는 실환경 1회 실행으로 확인하는 것이 좋다. FormatCustomDate는 m/d/y 고정: 원본 주석에 명시된 입력 형식을 그대로 따랐다. d/m/y 로케일 데이터를 넣으면 조용히 잘못된 값이 나온다. PowerShell 판(ConvertTo-SapDate.ps1)은 파싱 실패를 비종료 오류로 보고한다.ReservationExcelEdit.vbs의 C열 삭제는 위치 기반: 헤더 이름이 아니라 고정 위치라 원본 export 의 컬럼 순서가 바뀌면 엉뚱한 열이 지워진다. 원본 동작을 유지했지만, 헤더 기반으로 바꾸는 편이 안전하다.- git ≥ 2.21 필요:
working-tree-encoding을 지원하지 않는 구버전 git 으로 클론하면ReservationExcelEdit.vbs가 UTF-8 인 채로 체크아웃된다. 그 경우 편집기에서 "UTF-16 LE" 로 저장해야 한다.