블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 받은 트랙백

글 보관함

calendar

    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    


Count cells that contain specific text





=COUNTIF(rng,"*txt*")


특정 문자가 있는 cell들의 갯수를 알고자 한다면 COUNTIF 함수를 사용하시면 됩니다. 일반적으로 위와 같은 형태입니다. rng 는 cell들의 Range를 말합니다. txt 는 cell이 포함하고 있는 문자를 말하는 것이구요. *는 wildcard 죠 어떤 문자이든 상관 없다는 겁니다. 그러니까 *txt* 는 txt 만 포함돼 있으면 아무거나 괜찮다 입니다.




예를 들어 아래 공식을 보시죠.

=COUNTIF(B4:B11,"*a*")

이렇게 하면 B4에서 B11 사이에 있는 cell들 중에서 a를 포함하고 있는 모든 cell들의 갯수를 표시할 겁니다.

이걸 응용해서 다음과 같이 사용할 수도있습니다.

=COUNTIF(rng,"*"&a1&"*")

이건 rng 범위 안에서 a1 cell 에 있는 문자를 포함하고 있는 cell들의 갯수를 구할 겁니다.


저작자 표시 비영리 동일 조건 변경 허락
신고


7개월 만에 글을 쓰는 군요.

그 동안 iOS  앱 개발 프로젝트에 참가하면서 글이 중단 된 거 같은데...

Mobile Automated Testing Framework이 없어서 열심히 Manual Testing을 하느라고 바빴습니다.

FleetService 와 관련해서 Driver 들의 주행 정보를 수집하고 Driver 들에게 필요한 정보들을 제공해 주는 앱을 개발하고 있습니다.


엊그제 Prem이라는 동료가 와서 부탁한게 있어서...

제가 엑셀 프로그래밍을 업무에 몇번 활용했더니 그게 소문이 났는지 저한테 엑셀 프로그래밍을 부탁하더라구요.


데이터소스에서 데이터 수천개를 뽑아서 A 컬럼에 넣고 또 수천개를 뽑아서 C 컬럼에 넣었는데..


A 컬럼에 있는 데이터들을 일일이 가져와서 C 컬럼 어디엔가 있는지 없는지를 확인해야 한다고 하더라구요.


로직을 잘 고민해 보니까 컬럼간 비교보다는 C 컬럼에 데이터를 다른 sheet에 넣어서 sheet 내의 데이터들을 비교하는 로직으로 만들면 코드가 훨씬 더 간편해 질 것 같더라구요.





예전에 사용해 봤던 UsedRange 하고 늘 사용하고 있는 VLookup 함수를 사용하면요...


그래서 이렇게 만들어 봤습니다.


Sub CompareData()
    Dim rngCell As Range
    For Each rngCell In Worksheets("Sheet1").UsedRange
        On Error Resume Next
        Sal = Application.WorksheetFunction.VLookup(Sheet1.Range(rngCell.Cells.Address), Worksheets("Sheet2").UsedRange, 1, False)
        If Err.Number <> 0 Then
            Let rngCell.Interior.Color = RGB(255, 36, 36)
        End If
    Next
End Sub



rngCell 이라는 Range 변수를 선언해 두고 For Each 문을 돌립니다.


rngCell In Worksheets("Sheet1").UsedRange


이렇게 돌리면 Sheet1 에 있는 각각의 데이터 수 만큼 For 문이 돕니다.


On Error Resume Next

이것은 에러가 났을 경우 에러처리 하지 말고 그냥 그 다음 것을 실행하라는 겁니다.

나중에 VLookup 을 했을 때 찾는 데이터가 없으면 N/A 로 에러 처리 되거든요..

그 때 catch  해서 그 이벤트를 handling 하려고 이렇게 했습니다.


Sal = Application.WorksheetFunction.VLookup(Sheet1.Range(rngCell.Cells.Address), Worksheets("Sheet2").UsedRange, 1, False)


VLookup 함수를 이용했는데요. For 문이 돌면서 Sheet1의 각 데이터가 하나씩 골라질 텐세 그 각 Range를 VLookup의 첫번째 파라미터로 놓고요. Sheet2 의 모든 UsedRange를 두번째 파라미터에 넣습니다.

세번째 파라미터 1은 첫번째 값을 가져 온다는 얘기고 마지막 False 는 exact match 를 사용한다는 겁니다.


이렇게 되면 Sheet1의 해당 데이터가 Sheet2에 있으면 그 값이 Sal 에 할당이 되고 없으면 N/A 이렇게 에러가 할당이 됩니다.


이 때 On Error Resume Next 를 하지 않았다면 그냥 에러 처리가 될 텐데 그게 있어서 그 다음 라인으로 넘어갑니다.



그 다음에 IF 문이 있는데요.


만약에 에러가 발생하면 해당 Cell의 Interior 색을 빨간색으로 하라는 겁니다.


그러면 Sheet1의 어떤 값이 Sheet2에 없을 경우 해당 Cell 이 빨갛게 칠해 지는 겁니다.


UsedRange와 VLookup 두개의 함수로 동료의 업무를 깔끔하게 해결해 줬네요.. :)

저작자 표시 비영리 동일 조건 변경 허락
신고

Excel Macro로 HP QC 접속하기

2014.12.27 06:01 | Posted by 솔웅


현재 참여하고 있는 프로젝트에서는 Defect Management 를 위해 HP ALM 을 사용하고 있습니다.


Full name은 HP Application Lifecycle Management 이고 흔히 HP QC (Quality Center) 라고들 하더라구요.


이름 그대로 어플리케이션의 Lifecycle을 관리하는 툴인데 현재 프로젝트에서는 Defect 관리만 하고 있습니다. 이 외에 Rally 를 사용해서 Agile Methodology 를 구현하고 있구요.


Automation Testing 을 위해서는 Jenkins 를 사용하고 있습니다.


오늘 글에서는 HP QC 에 있는 데이터를 Excel Macro를 이용해서 불러오는 방법을 정리하겠습니다.


불러온 데이터를 가공해서 관련 테스터나 개발자 혹은 관리자에게 Report 를 이메일로 보내는 프로그램을 개발해서 현재 사용하고 있는데요.


오늘 글에서는 엑셀 매크로를 이용해서 HP QC에 접근하는 방법만 다루겠습니다.

(원문)





가장 먼저 해야할 일이 HP QC에 ID/PW를 입력해서 접근 권한을 얻는 겁니다.


이 때 ID/PW 이외에 Domain과 Project 정보를 함께 제공해야 합니다.


소스코드를 볼까요?


  1. Sub ConnectToQualityCenter()  
  2.   
  3. Dim qcURL As String  
  4. Dim qcID As String  
  5. Dim qcPWD As String  
  6. Dim qcDomain As String  
  7. Dim qcProject As String  
  8. Dim tdConnection As Object  
  9.   
  10. On Error GoTo err  
  11.    qcURL = <QC URL> 'Example : https://<server url>/qcbin  
  12.    qcID = <your User ID>  
  13.    qcPWD = <Your password>  
  14.    qcDomain = <Domain Name>  
  15.    qcProject = <Project Name>  
  16. 'Display a message in Status bar  
  17.    Application.StatusBar = "Connecting to Quality Center.. Wait..."  
  18. ' Create a Connection object to connect to Quality Center  
  19.    Set tdConnection = CreateObject("TDApiOle80.TDConnection")  
  20. 'Initialise the Quality center connection  
  21.    tdConnection.InitConnectionEx qcURL  
  22. 'Authenticating with username and password  
  23.    tdConnection.Login qcID, qcPWD  
  24. 'connecting to the domain and project  
  25.    tdConnection.Connect qcDomain, qcProject  
  26. 'On successfull login display message in Status bar  
  27.    Application.StatusBar = "........QC Connection is done Successfully"  
  28.    Exit Sub  
  29. err:  
  30. 'Display the error message in Status bar  
  31. Application.StatusBar = err.Description  
  32. End Sub 



우선 URL,ID,PWD,Domain 그리고 Project 정보를 해당 변수에 대입시켰죠.


그리고 Application.StatusBar 프로퍼티는 일이 진행되는 동안 메세지를 표시하도록 합니다.


그 다음 19번째 줄에서 HP QC에 connect 할 객체를 생성합니다.

TDApiOle80.TDConnection 를 사용해서 생성하시면 됩니다.


21번째 줄에서는 URL을 사용해서 connection을 초기화 하구요 23번째 줄에서는 ID와 PW를 제공합니다.


25번째 줄에서 도메인과 프로젝트 정보를 제공해서 로그인에 필요한 모든 정보가 제공되게 됩니다.


여기까지 오면 HP QC에 무사히 접속한 겁니다.


27번째 줄에서는 무사히 접속했다는 메세지를 뿌려 줍니다.


그 다음에 Exit Sub를 해서 HP QC 접속 함수를 완료 합니다.

만약에 에러가 있으면 29번째 줄로 건너 뛰어서 에러 메세지를 뿌려주고 End Sub를 하게 되구요.


전달하는 URL은 항상 https://<server url>/qcbin  형태가 됩니다.

저작자 표시 비영리 동일 조건 변경 허락
신고


Rawdata를 받아들고 Client 가 요청하는 통계를 만들다 보면 여러 가지 방법을 사용해야 될 때가 있습니다.


예전에 해당 날짜가 속한 주의 월요일을 구해야 될 일이 있었는데 그 때 사용했던 Formula 입니다. 



=TODAY()-WEEKDAY(TODAY(),2)+1


이 글을 작성하는 날짜가 12/12/2014 입니다.

그러니까 이번주의 월요일은 12/8/2014 이니까 이게 표시가 되겠네요.



함수를 보면 처음  TODAY() 는 오늘 날짜를 표시해 주는 함수 이죠.


그리고 WEEKDAY()의 첫번째 인자는 날짜가 되겠구요.

두번째 parameter 는 처음에 이해하기 좀 복잡하더라구요.


저는 2를 선택했는데요. 이 의미는 일주일을 1~7로 할당하고 1은 Monday가 된다는 얘기 입니다.

만약에 3을 선택하면 Monday 부터 시작하긴 하지만 시작하는 숫자는 0이라는 얘기 입니다.


오늘이 금요일이니까 두번째 것을 선택하면 결과 값은 5가 되겠고 세번째 것을 선택하면 결과 값은 4가 되겠죠.


일단 2를 선택했으니까 결과 값은 5가 나올 겁니다.


그러니까 Today (금요일) 에서 5를 빼면 5일 전을 말하니까 일요일이 되겠죠. 원하는 값은 월요일이니까 여기에 다시 1을 더해 준 겁니다.


그러면 오늘이 속한 주의 월요일을 구할 수 있습니다.




이 공식이 얼마나 자주 사용 될 지는 모르겠지만...


하여간 제가 하는 일에서는 사용을 했습니다.


주별 Defect Creation 경과를 그래프로 표시해야 되서 이 공식을 이용 했었죠.



저작자 표시 비영리 동일 조건 변경 허락
신고

엑셀 VLOOKUP 함수 사용하기

2014.12.11 23:35 | Posted by 솔웅


어제 업무에 사용했던 함수를 하나 정리해 보겠습니다.


실제 회사 데이터를 올릴 수 는 없어서 가상으로 아래의 상황을 설정했습니다.



작년과 올해에 여러곳에서 마라톤을 완주 했습니다.

위와 같이 정리 돼 있는데 첫번째 표에 해당 City의 2014년도의 기록을 넣고 싶습니다.


이럴경우 VLOOKUP을 사용하면 되는데요.


=IFERROR(VLOOKUP(B6,$G$6:$H$11,2,FALSE),"No")


이렇게 사용하면 됩니다.



우선 VLOOKUP 함수부터 보면 첫번째 argument (B6)는 비교할 데이터 입니다.

첫번째 칸에서는 Chunchon 이 되겠죠.


그리고 두번째($G$6:$H$11)는 이 Chunchon 이라는 데이터랑 비교할 범위입니다.

G6:H11 이 범위인데 여기에 $를 사용한 이유는 나중에 다른 셀에도 적용하기 위해서 해당 셀을 더블클릭하거나 Drag 할 때 이 값이 변하지 않도록 하기 위해서 입니다.

첫번째 인자인 B6는 $이 없으니까 Drag 하면 B7-B8-B9... 이런식으로 숫자가 자동 증가하게 됩니다.


그리고 세번째 인자인 2 는 두번째 값을 셀에 넣겠다는 겁니다.

Chunchon 이랑 같은 값이 오면 그 라인의 두번째 값을 취하겠다는 겁니다.

(그런데 오른쪽에는 Chunchon 이 없네요. 이런 경우는 조금 있다가 설명드리겠습니다.)

대신 Delhi를 보면 3:18 이 두번째 값입니다.


마지막에 FALSE는 Chunchon 이랑 정확하게 match 되어야 한다는 조건이고 TRUE 를 사용하면 비슷한 단어가 있으면 match 됐다고 보라는 겁니다.


이렇게 하면 VLOOKUP은 완료 됐는데요.


아까 봤듯이 CHUNCHON이라는 도시가 오른쪽 표에 없습니다.

이런 경우 #N/A 라고 표시가 될 텐데, 이게 보기 싫으면 다른 문자를 표시할 수 있습니다.


그게 IFERROR 함수 입니다.

만약 결과가 ERROR 이면 No 라는 문자를 표시하라는 거죠.


이렇게 하면 아래와 같은 결과가 나옵니다.




작년과 올해 모두 참가한 마라톤 대회는 Roterdam과 Boston  대회이군요.

Roterdam 대회는 1시간을 앞당겼고 Boston 대회는 50여분이 늦춰졌네요.



뭐 이게 있을 법한 일인지는 모르겠지만요.


하여간 VLOOKUP과 IFERROR 를 잘 사용하면 위와 같이 데이터를 가공할 필요가 있을 때 아주 유용하게 사용 하실 수 있습니다.




저작자 표시 비영리 동일 조건 변경 허락
신고


지지난주 토요일 Automation Test 를 이용해서 Production Deployment 작업을 진행해서 일을 훨씬 수월하게 끝마칠 수 있었습니다.


총 300여개가 넘는 job (test case) 들이 있었고 이것을 실행하는 시간은 총 27시간 이었습니다.

그런데 Jenkins 에 20개의 Agents들이 있어서 이 작업을 1시간 반만에 끝 마칠 수 있었죠.


예전에 매뉴얼로 할 때는 저녁 6시가 넘어서까지 일했다고 하던데...

Automation Test 를 이용한 지난번 Production Deployment는 아침 10시에 끝날 수 있었습니다.


엄청난 시간 절약이고 회사 입장에서는 엄청난 비용 절감이죠.


이걸 Client에게 제대로 인식시켜야 하니까 이 내용을 PPT에 담아서 고객에게 보여줘야겠죠.


저는 정말 PPT 작업 못 하는데... 그나마 제가 낫다고 저보고 하라그래서 슬라이드 한 두장정도 만들어서 줬어요.


물론 담당자가 좀 더 수정을 했지만요.


그거 만들면서 시간을 많이 계산해야 했습니다.


분:초 로 돼 있던 시간을 초로 계산하고 또 초를 다시 분:초로 만들고 분을 시:분으로 만들고 하는 것들이요.


그래서 이 내용들을 정리해 두려구요.



1. 분:초 를 초로 변환하기


07:32

 452


7분 32초를 이렇게 초로 계산하려면 아래와 같이 하면 됩니다.


=LEFT(위치,2)*60+MID(위치,4,2)



2. 초를 분:초로 변환하기


303.3384615

 05:03


303.3384615 초를 분:초 로 변환 하려면 아래와 같이 하면 됩니다.


=TEXT(TIME(,,위치),"mm:ss")




이렇게 한 다음에 =위치/86400 을 하는 방법도 있네요.

여기를 보시면 자세한 내용을 보실 수 있습니다.



3. 분을 시간:분 으로


1643

 27hrs23mins


1643분을 시간:분으로 표시하려면 아래와 같이 하면 됩니다.


=INT(위치/60)&"hrs"&MOD(위치,60)-MOD(위치,1)&"mins"



보고서 같은 거 작성할 때 필요할 때가 있을 것 같네요.


저작자 표시 비영리 동일 조건 변경 허락
신고


어제 필터링 한 후 Range 내의 Row의 갯수를 구하는 방법을 알아 봤는데요.


레인지.SpecialCells(xlCellTypeVisible).Rows.Count


이게 필터링을 여러 조합으로 하고 난 후 제대로 작동을 안 하는 경우가 있더라구요.


그래서 이 방법 말고 For 문을 돌려서 Row의 갯수를 구했습니다.


   CRRCnt = 0
   
    For Each Cell In 레인지.SpecialCells(xlCellTypeVisible).Cells
            CRRCnt = CRRCnt + 1
            'Debug.Print CRRCnt
    Next


CRRCnt라는 Integer 를 정의하고 난 후 Range의 보이는 Cell들을 For 문을 돕니다.

제 경우는 Range가 한개의 field안에 있어서 이렇게 했는데요.


더 정확하게 하려면 Cell이 아니라 Rows로 for 문을 돌려야겠군요.

이렇게는 확인을 안 해 봤습니다.

이번 작업의 경우엔 저렇게 하면 되기 때문에 그냥 Cells를 For 문을 돌렸습니다.


이렇게 For 문을 돌리면서 CRRCnt를 하나씩 증가시키면 필터링 한 후 레인지 내의 보이는 Row 수를 구할 수 있습니다.


레인지.SpecialCells(xlCellTypeVisible).Rows.Count 가 생각대로 제대로 작동하지 않으면 위와같이 해결하면 됩니다.



저작자 표시 비영리 동일 조건 변경 허락
신고


원래 이 Tip 도 지난 글과 같이 올리려고 했는데 애초 생각과 다르게 이전에 만들어 놨던 다른 component들까지 다 정리하는 바람에 따로 정리하게 됐습니다.


Sub 평균구하기함수()

    Dim firstCell As Range
    Dim lastCell As Range
    Dim lastRow As Double
    Dim rngtest As Range
    Dim 평균 As String

    Call clickLink("Cell주소")

    ''''''' get the first Cell to calculate
    Set firstCell = getBelowCell2("필드이름1")
   
    ''''''' get the last row to calculate
    lastRow = activateLastrow2Cal2("필드이름2")
    
    ''''''' get the last Cell to calculate
    Set lastCell = firstCell.Offset(lastRow - firstCell.Row, 0)
   
    Call filterOption("필드이름3", "1")
    Call filterOption("필드이름4", ">0")
   
    ' Get count of rows
    Set rngtest = Range(firstCell, lastCell)
    rngtest.Select
   
    평균 = WorksheetFunction.Average(rngtest.SpecialCells(xlCellTypeVisible))
   
    Call writeTable5("Sheet 이름", 0, 0, 평균 , "K11")

End Sub



위에 한글로 표기한 것은 해당 엑셀에 맞춰서 적당한 값을 넣어야 하는 겁니다.

변수명이나 필드이름 등은 회사 업무와 관련이 있는 거라서 회사 업무 내용을 공개하지 않기 위해 이름을 변경했습니다.


여기서 살펴볼 것은 아래 라인 입니다.


평균 = WorksheetFunction.Average(rngtest.SpecialCells(xlCellTypeVisible))


나머지는 이전 글에 각 함수 내용을 올려 놓았으니 그 글을 참조하시면 됩니다.

진행 순서도 똑 같구요.

필터링 후 선택된 Range의 평균을 구하는 것은 WorksheetFunction.Average(레인지.SpecialCells(xlCellTypeVisible)) 를 사용하면 됩니다.


결과 값은 String에 담구요.

이걸 Integer나 Double에 담아봤더니 에러가 나더라구요.

Converting을 해서 담던가 아니면 그냥 String 변수에 담아야 합니다.


한가지 더 참조한다면 아래 라인 입니다.


Call filterOption("필드이름4", ">0")


greater than 0 로 필터링을 어떻게 할 까 궁금했는데 그냥 위와 같이 >0 을 전달하면 되는군요.

filterOption() 함수는 이전 글에 있으니 보시고 싶으시면 바로 전 글을 보시면 됩니다.



저작자 표시 비영리 동일 조건 변경 허락
신고


엑셀 프로그래밍 추가 작업을 하고 있는데 몇가지 새로운 로직이 나왔습니다.

필터링 후 row의 갯수를 구하는 것과 필터링 후 특정 필드의 Average를 구하는 것입니다.


우선 필터링 후 row의 갯수를 구하는 것은 아래와 같이 하면 됩니다.


Range.SpecialCells(xlCellTypeVisible).Rows.Count


이걸 제 작업에서는 아래와 같이 활용했습니다.


Sub Sub이름()

    Dim firstCell As Range
    Dim lastCell As Range
    Dim lastRow As Double
    Dim rngtest As Range
    Dim count As Integer

    Call clickLink("링크")

    ''''''' get the first Cell to calculate
    Set firstCell = getBelowCell2("필드이름1")
   
    ''''''' get the last row to calculate
    lastRow = activateLastrow2Cal2("필드이름2")
    
    ''''''' get the last Cell to calculate
    Set lastCell = firstCell.Offset(lastRow - firstCell.Row, 0)
   
    Call filterOption("필드이름3", "1")
   
    ' Get count of rows
    Set rngtest = Range(firstCell, lastCell)
   
    count = rngtest.SpecialCells(xlCellTypeVisible).Rows.Count
   
    Call writeTable4("Sheet Name", 0, 0, count, "G6")

End Sub


특정 Sheet로 가서 필터링 한 후 특정 필드의 row 갯수를 구하는 겁니다.





우선 제가 작업하는 엑셀 파일에는 첫 sheet 에 링크가 있어서 원하는 sheet로 링크를 클릭해서 가도록 돼 있습니다.


Sub clickLink(link As String)
    Call goToSheet("링크가 있는 sheet name")
    Worksheets("링크가 있는 sheet name").Range(link).Hyperlinks(1).Follow NewWindow:=False, AddHistory:=True
    On Error Resume Next
        ActiveSheet.ShowAllData
    On Error GoTo 0
End Sub


이게 clickLink() 함수 인데요.

Link가 있는 Cell 주수를 String 파라미터로 받습니다. 그리고  goToSheet() 로 링크가 있는 sheet name을 파라미터를 전달합니다.


Sub goToSheet(sheetName As String)
    Sheets(sheetName).Select
    Range("B4").Select
End Sub


goToSheet()은 sheetName을 파라미터로 전달 받아서 해당 Sheet로 이동을 하는 함수 입니다.


다시 clickLink()를 보면 goToSheet() 다음에 해당 링크를 클릭합니다.


간단하게 말하면 clickLink()에 링크를 전달하면 그것을 클릭하는 겁니다.


그 다음에 getBelowCell2() 에서 값을 전달받아 firstCell Range에 담는데요.


Public Function getBelowCell2(cellVal As String) As Variant
    Call ActivateCell(cellVal)
    Set getBelowCell2 = ActiveCell.Offset(1, 0)
End Function


getBelowCell2 는 필드 이름(String)을 전달 받아서 바로 그 밑의 Cell을 return 합니다.

두번째는 activateLastrow2Cal2()에서 return 받은 Double형을 lastRow에 담습니다.


Public Function activateLastrow2Cal2(cellVal As String) As Double
    Call getBelowCell(cellVal)
    activateLastrow2Cal2 = ActiveCell.End(xlDown).Row
End Function


activateLastrow2Cal2()는 필드이름을 파라미터로 전달 받아서 그 필드의 가장 마지막 row 번호를 return 합니다.


이 값을 가지고 계산할 필드의 마지막 Row를 계산합니다.


Set lastCell = firstCell.Offset(lastRow - firstCell.Row, 0)


그러면 계산할 필드의 첫번째 Cell과 마지막 Cell을 확보한 겁니다.


그 다음에 필터링을 하는데요.


Sub filterOption(cellVal As String, filterVal As String)
    ActivateCell ("필드이름")
    'ActivateCell.Offset(0, -1).Select

    If ActiveSheet.FilterMode Then

    Else: Rows(ActiveCell.Row).Select
        Selection.AutoFilter
        Selection.AutoFilter
    End If
    
    Call ActivateCell(cellVal)
    ActiveCell.AutoFilter Field:=ActiveCell.Column, Criteria1:=filterVal
End Sub


Sub ActivateCell(cellVal As String)
    Cells.Find(What:=cellVal, After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
        xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
        , SearchFormat:=False).Activate
End Sub


우선 ActivateCell은 필드 이름을 전달 받아서 해당 필드이름(제목)이 있는 Cell을 활성화 시키는 겁니다.

filterOption()은 필터링할 필드 이름과 필터링할 값을 파라미터로 받아서 필터링을 하는 겁니다.

그 전에 IF 문에 로직을 만들었는데 그건 제가 작업하는 엑셀 파일에서 이렇게 해야 되서 넣은 겁니다.


이러면 계산할 필드의 첫번째와 마지막 Cell을 구했고 조건에 맞게 필터링도 했습니다.


    Set rngtest = Range(firstCell, lastCell)
   
    count = rngtest.SpecialCells(xlCellTypeVisible).Rows.Count
   
    Call writeTable4("Sheet Name", 0, 0, count, "G6")


그 다음에 나오는 소스코드 입니다.

우선 첫번째 cell 에서 마지막 cell 까지를 rngtest라는 Range에 담고 이 range의 row 수를 count 에 담습니다.

writeTable4()는 전달하는 Sheet Name 의 해당 위치(위에서는 G6) 에 count 값을 write 하려고 만든 겁니다.


Sub writeTable4(sheetName As String, firstNum As Integer, secondNum As Integer, resultVal As Integer, writeCell As String)
    Dim writeVal1 As Range
    Sheets(sheetName).Select
    Set writeVal1 = Range(writeCell).Offset(firstNum, secondNum)
    writeVal1.Value = resultVal
    Range("D6").Select
End Sub


그 내용을 보면 전달받은 sheet name을 가진 sheet를 활성화 시키고 전달받은 위치 ("G6") 에 전달받은 값을 write 하는 겁니다.

writeVal1에 offset()을 사용한 것은 조건에 따라서 write할 Cell의 위치("G6") 를 바꾸기 위해서 입니다.


count = rngtest.SpecialCells(xlCellTypeVisible).Rows.Count


이 부분을 정리하려고 했는데 이전에 만들어 놨던 여러 Component들까지 다 살펴 봤네요.



저작자 표시 비영리 동일 조건 변경 허락
신고


지난번 VBA 디버깅 툴 사용법 다루면서 Debug.print 문도 배웠는데요.

Immediate Window 에 출력되는 양이 한정돼 있더라구요.

그래서 제가 원하는 전체 로그를 볼 수 있는 방법을 알아봤더니.. 자체적으로 Immediate Window의 출력량을 늘리는 법은 못찾았고 대신에 로그를 파일로 저장하면 되겠더라구요.

그래서 로그를 파일로 저장하는 예제 몇개 정리해 둘까 합니다.



Dim s As String
Dim n As Integer

n = FreeFile()
Open "C:\test.txt" For Output As #n

s = "Hello, world!"
Debug.Print s ' write to immediate
Print #n, s ' write to file

Close #n

Open .... For Aoutput As #n 이라는 구문이 있군요.

해당 텍스트 파일을 #n으로 세팅해 놓고 Print #n, 출력할 문자열 ' write to file 을 하고 마지막에 #n을 Close 해 줍니다.

(아직 실습을 안 해 봐서 정확히 이게 맞는건지는 확실하지 않습니다.

이렇게 Input과 Output 사용법이 약간 다른가 봅니다.

Sub ReadFile()

'again, we need this strange thing to exist so that ...

Dim fso As New FileSystemObject

'the file we're going to read from

Dim ts As TextStream

'... we can open a text file with reference to it

Set ts = fso.OpenTextFile("C:\Wise Owl\info.txt", ForReading)

'keep reading in lines till no more

Dim ThisLine As String

Dim i As Integer

i = 0

Do Until ts.AtEndOfStream

ThisLine = ts.ReadLine

i = i + 1

Debug.Print "Line " & i, ThisLine

Loop

'close down the file

ts.Close

End Sub


이건 약간 다른 방법 같은데... 이번 주말에 전부 한번 실제로 돌려 봐야겠네요.


저작자 표시 비영리 동일 조건 변경 허락
신고
이전 1 2 3 다음

티스토리 툴바