::: 까만콩 빈이네 :::
까만콩 빈이네의 살아가는 이야기를 기록합니다
RSS
  • Home
20150908150230

9월 8 2015

엑셀(EXCEL) – 시트 통합, 월간년간보고서 작성 및 특정자료(대리점) 추출

 

보통 일간 주문현황이나 생산현황 등 일간 보고서를 양식으로 만들고 각 시트마다 자료를 정리하고
월간이나 분기, 반기, 년간 별로 보고 자료를 작성해야하는 경우 그 자료를 취합하기가 만만찮은
작업입니다. 일간 자료를 시트마다 전체 복사해서 한 시트에 모으는 것도 장난?아닌데 년간 자료를
만드는 것은 상상하기도 힘든 작업입니다. (물론 일간이 모여 월간자료가 생성되면 조금은 덜하지만)

http://www.clien.net/cs2/bbs/board.php?bo_table=kin&wr_id=3523876
(엑셀 – 여러 시트에서 특정 값이 들어있는 행 가져오기)

며칠간 도저히 버그를 잡지 못해 일단 올리고 봅니다. 루프가 돌기는 도는데 계속 클릭을 하는 순서에
따라 순차적으로 검색이 되고 안되기를 하는데 원인을 찾지를 못해서 사용은 할 수 있을 것 같아서
일단 올리고 버그는 더 잘아시는 분이 코드에서 찾아서 댓글로 올려 주세요. …

ps> 버그 잡았습니다. … 역시 벌레는 찾는 곳이 아닌 다른 곳에 숨어 있었군요.

For Each sht In wrk.Worksheets
If sht.Name = “Master” Or sht.Name = “ExtData” Then

sht.Delete

Exit Sub
End If
Next sht

위의 삭제 시트 코드와 저 아래의 시트 삭제 코드에서 Exit Sub를 주석처리하면 됩니다.

루틴을 돌려보니 한 번은 되고 한 번은 안되고 하는 이유가 보이네요. 시트가 없으면 실행되고

시트가 있으면 시트 삭제하고 Sub를 마쳐버려서 그렇네요.

 

유저폼의 리스트를 클릭하면 하나는 되고 그다음 클릭은 되지 않고 아무거나 눌러서 가짜 클릭을?
만들고 원하는 리스트를 클릭하면 자료가 만들어지는 순환구조상으로는 아무 문제가 없는데?
문제가 나타나는 기이한 버그?입니다. 여러 방법으로 처리를 해 보았는데 똑같은 결과가 나오는
것으로 보아 해당 코드에 버그가 있는데 도저히 보이지를 않습니다. 아래 코드입니다.

Do While Range(“START”).Offset(i, 1) <> “”
If Left(Range(“START”).Offset(i, 2), InStr(Range(“START”).Offset(i, 2), “-“) – 1) = FindStr
Then
Range(Range(“START”).Offset(i, 0), Range(“START”).Offset(i, 17)).Copy

intCount = intCount + 1

trg.Range(“A1”).Offset(intCount, 0).Select
trg.Paste

End If

i = i + 1
Loop

우선 워크시트를 통합하는 코드와 폴더(디렉토리)에 모여있는 모든 엑셀 화일을 통합하는코드입니다.

Option Explicit

Sub MergeWBs()

Dim wbDst As Workbook
Dim wbSrc As Workbook

Dim wsSrc As Worksheet

Dim MyPath As String
Dim strFilename As String

Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False

MyPath = “C:\Data”

Set wbDst = ThisWorkbook

strFilename = Dir(MyPath & “\*.xls”, vbNormal)

If Len(strFilename) = 0 Then Exit Sub

Do Until strFilename = “”

Set wbSrc = Workbooks.Open(Filename:=MyPath & “\” & strFilename)

Set wsSrc = wbSrc.Worksheets(1)

wsSrc.Copy after:=wbDst.Worksheets(wbDst.Worksheets.Count)

wbSrc.Close False

strFilename = Dir()

Loop

wbDst.Worksheets(1).Delete

Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True

End Sub

Sub MergeWSs()

Dim wrk As Workbook

Dim sht As Worksheet
Dim trg As Worksheet

Dim rng As Range
Dim colCount As Integer

Set wrk = ActiveWorkbook

Application.DisplayAlerts = False

For Each sht In wrk.Worksheets
If sht.Name = “Master” Or sht.Name = “ExtData” Then

sht.Delete

Exit Sub
End If
Next sht

Application.DisplayAlerts = True
Application.ScreenUpdating = False

Set trg = wrk.Worksheets.Add(after:=wrk.Worksheets(wrk.Worksheets.Count))
trg.Name = “Master”
Set sht = wrk.Worksheets(1)
colCount = sht.Cells(1, 255).End(xlToLeft).Column

With trg.Cells(1, 1).Resize(1, colCount)
.Value = sht.Cells(1, 1).Resize(1, colCount).Value

.Font.Bold = True
.Interior.Color = vbGreen
End With

For Each sht In wrk.Worksheets
If sht.Index = wrk.Worksheets.Count Then
Exit For
End If

Set rng = sht.Range(sht.Cells(2, 1), sht.Cells(65536, 1).End(xlUp).Resize(, colCount))

trg.Cells(65536, 1).End(xlUp).Offset(1).Resize(rng.Rows.Count, rng.Columns.Count).Value =
rng.Value

Next sht

trg.Activate

Range(“A2″).Select
ActiveWorkbook.Names.Add Name:=”START”, RefersToR1C1:=”=Master!R2C1″

trg.Columns.AutoFit

Call ExtUniqItemRng(UserForm1.ListBox1)

UserForm1.Show

Application.ScreenUpdating = True

End Sub
통합된 자료에서 추출하고자 하는 문자열을 구하는 루틴입니다. 제 팁에서 자주 사용되고 있는 루틴을
변형하여 특정 값에서 문자를 추출하고 그 추출된 문자열의 중복 항목을 제거하여 사용자폼의 리스트에
정렬하는 방법입니다. VBA에서 Userform을 하나 만드시고 Listbox하나를 만들어 Object로 넘기는
소스입니다.

Sub ExtUniqItemRng(obj As Object)

Dim TempStr As String

Dim intNum As Integer
Dim NumCnt As Integer

Dim Cell As Range
Dim NoDupes As New Collection

Dim i As Integer, j As Integer
Dim Swap1, Swap2, item
Dim UniqStr As String

Dim TgtCel As Range
Dim SelRng As Range

Set SelRng = Range(“C2”, Range(“C2”).End(xlDown))

Application.ScreenUpdating = False

On Error Resume Next

For Each Cell In SelRng

If Len(Cell.Value) > 0 Then ‘ 빈셀을 포함시키지 않음
‘ Add method의 2번째 인자는 문자열이어야만 함
NoDupes.Add Left(Cell.Value, InStr(Cell.Value, “-“) – 1), Left(CStr(Cell.Value), InStr(CStr
(Cell.Value), “-“) – 1)

End If

Next Cell

On Error GoTo 0

For i = 1 To NoDupes.Count – 1

For j = i + 1 To NoDupes.Count

If NoDupes(i) > NoDupes(j) Then

Swap1 = NoDupes(i)
Swap2 = NoDupes(j)

NoDupes.Add Swap1, before:=j
NoDupes.Add Swap2, before:=i
NoDupes.Remove i + 1
NoDupes.Remove j + 1

End If

Next j

Next i

For Each item In NoDupes

obj.AddItem item

Next item

Set Cell = Nothing

Application.ScreenUpdating = True

End Sub
Userform의 Listbox의 Listitem을 클릭할 때마다 List내용을 받아서 자료를 추출하는 소스입니다.

Sub ExtItemSelect(FindStr As String)

Dim i As Integer, cnt As Integer
Dim colCount As Integer, intCount As Integer
Dim wrk As Workbook

Dim sht As Worksheet
Dim trg As Worksheet

Dim Ccel As Range
Dim SelRng As Range

Set wrk = ActiveWorkbook

Application.DisplayAlerts = False

For Each sht In wrk.Worksheets
If sht.Name = “ExtData” Then

sht.Delete

Exit Sub
End If
Next sht

Application.DisplayAlerts = True
Application.ScreenUpdating = False

Set trg = wrk.Worksheets.Add(after:=wrk.Worksheets(wrk.Worksheets.Count))
trg.Name = “ExtData”

Set sht = wrk.Worksheets(1)
colCount = sht.Cells(1, 255).End(xlToLeft).Column

With trg.Cells(1, 1).Resize(1, colCount)
.Value = sht.Cells(1, 1).Resize(1, colCount).Value

.Font.Bold = True
.Interior.Color = vbRed
End With

Do While Range(“START”).Offset(i, 1) <> “”
If Left(Range(“START”).Offset(i, 2), InStr(Range(“START”).Offset(i, 2), “-“) – 1) = FindStr
Then
Range(Range(“START”).Offset(i, 0), Range(“START”).Offset(i, 17)).Copy

intCount = intCount + 1

trg.Range(“A1”).Offset(intCount, 0).Select
trg.Paste

End If

i = i + 1
Loop
Application.ScreenUpdating = True

Columns.AutoFit

End Sub
순환 논리는 맞는데 아무리 봐도 추출되지 않는 원인이 보이지 않으니 답답하지만
누가 잘 해결해 주실거라고 믿고 팁란에 올립니다.

첨부 화일 : 20150908-시트 통합, 월간년간보고서 작성 및 특정 자료 추출 보고

By vinipapa • 무른모 • 0 • Tags: Excel, Tip, 시트 통합, 엑셀, 자료 추출

20150903162008

9월 3 2015

엑셀(EXCEL) – 다대다(多對多) 항목 역전개(기준항목 변경)

 

세상이 발전?함에 따라 내용도 많아지고 서로 경쟁적으로 살아가다 보니 여러 자료들이
처음 설계될 때 미처 생각하지 못한 문제들이 나타나고 비대해져 버린 데이터들을 다시
역으로 가공하려고 하면 엄두도 안나는 일에 포기하고 마는 수가 있습니다.

http://www.clien.net/cs2/bbs/board.php?bo_table=kin&wr_id=3521638

경쟁 구도의 회사들을 잘 정리해 놓았는데 이것을 다시 기준을 바꾸어 새로 작성할려고하니
정말 엄두도 안나는 데이터에 포기하고 싶으셨는지 질문에 ㅠㅠ라고 눈물까지 흘리십니다.
일단 국내의 회사들도 무지 많을텐데 자료가 정리되지 않았다고 가정하여 진행을 합니다.

제가 이전에 올렸던 팁들에서 유용하게 사용하던 중복항목 제거 함수를 조금 더 발전시켜서
아래와 같이 만들었습니다. 참조 영역을 설정하고 중복제거된 데이터를 출력할 위치를 선택
바로 리스트를 만들 수 있도록 하였습니다.

Option Explicit

Sub ExtUniqItemRng()

Dim TempStr As String

Dim intNum As Integer
Dim NumCnt As Integer

Dim AllCells As Range, Cell As Range
Dim NoDupes As New Collection

Dim i As Integer, j As Integer
Dim Swap1, Swap2, item
Dim UniqStr As String

Dim TgtCel As Range
Dim SelRng As Range

Set SelRng = Application.InputBox(“추출 영역을 선택”, Type:=8)

Set TgtCel = Application.InputBox(“결과값을 저장할 셀을 선택”, Type:=8)

Set AllCells = SelRng

Application.ScreenUpdating = False

On Error Resume Next

For Each Cell In AllCells

If Len(Cell.Value) > 0 Then ‘ 빈셀을 포함시키지 않음
‘ Add method의 2번째 인자는 문자열이어야만 함
NoDupes.Add Cell.Value, CStr(Cell.Value)

End If

Next Cell

On Error GoTo 0

For i = 1 To NoDupes.Count – 1

For j = i + 1 To NoDupes.Count

If NoDupes(i) > NoDupes(j) Then

Swap1 = NoDupes(i)
Swap2 = NoDupes(j)

NoDupes.Add Swap1, before:=j
NoDupes.Add Swap2, before:=i
NoDupes.Remove i + 1
NoDupes.Remove j + 1

End If

Next j

Next i

For Each item In NoDupes

UniqStr = UniqStr & “:” & item

Next item

NumCnt = 0
TempStr = “”

For intNum = 1 To Len(UniqStr)
If Mid(UniqStr, intNum, 1) <> “:” Then

TempStr = TempStr + Mid(UniqStr, intNum, 1)

TgtCel.Offset(NumCnt – 1, 0).Value = TempStr

Else

NumCnt = NumCnt + 1

TempStr = “”

End If

Next intNum

Set Cell = Nothing

Application.ScreenUpdating = True

End Sub

위 루틴을 실행해서 국내 회사들의 중복 항목을 제거해서 리스트를 만듭니다. 물론 리스트가
만들어져 있으면 이 루틴은 생략하시고 진행하시면 됩니다. 이제 경쟁회사들의 리스트를 선택
해외 경쟁사들을 추려내는 루틴입니다.

Sub ExtCompetitionCom()

Dim i As Integer, j As Integer
Dim rcnt As Integer, ccnt As Integer, ColCnt As Integer

Dim RCel As Range
Dim Ccel As Range

Dim RngCel As Range
Dim ComList As Range

rcnt = Application.CountA(Range(“A1”, Range(“A1”).End(xlDown)))

Set ComList = Application.InputBox(“국내회사 영역을 선택”, Type:=8)

ColCnt = 0
ccnt = ComList.Rows.Count – 1

Application.ScreenUpdating = False

For Each Ccel In ComList

For i = 2 To rcnt

For j = 2 To ccnt

If Ccel.Value = Cells(i, j).Value Then

Ccel.Offset(0, ColCnt + 1).Value = Cells(i, 1).Value

End If

Next j

ColCnt = ColCnt + 1

Next i

ColCnt = 0

Next

Application.ScreenUpdating = True

End Sub

Private Sub CommandButton1_Click()

Call ExtUniqItemRng

End Sub

Private Sub CommandButton2_Click()

Call ExtCompetitionCom

End Sub

이렇게 다 해결해서 올리면 간단해 보이는데 이 루틴을 최적화시키는 과정에서 머리 쥐납니다.
루틴은 머리에서 맴도는데 생각처럼 잘 되지 않으면 담배도 못피는 저는 쓴 커피 한 잔 마시고
돌아와서 한 번 더 생각 해 보면 어느 정도 실마리가 보이더군요.

첨부 화일 :20150903-다대다 항목 역전개

By vinipapa • 무른모 • 0 • Tags: 다대다 역전개, 엑셀, 역전개

20150902190321

9월 2 2015

엑셀(EXCEL) – 일정 영역에서 행별 중복항목 제거 및 추출 방법

 

아무거나 질문 게시판에 엑셀관련 아래와 같은 무시 무시한 질문과 답변이 올라왔습니다.
해석하면 자동으로 가로로 된 영역에서 중복 값을 제거하고 자기 영역에 다시 복사하여
붙이기를 하는 매크로입니다. 머리가 아프지만 저의 삽질 본능을 깨우는 내용입니다. ㅠㅠ

http://www.clien.net/cs2/bbs/board.php?bo_table=kin&wr_id=3517395
([excel] 해당 코드에서 selection에서 자꾸 에러가 납니다. 원인분석을 부탁드립니다.)

엑셀은 사실 숫자를 다루기도 하지만 데이터를 더 많이 다루는 프로그램입니다. 자료를 작성
할 때는 데이터베이스처럼 필드 개념의 열과 데이터 개념의 행으로 보통 무의식적으로 만듭니다.
그래서 엑셀 내장 함수에도 아래로 입력된 데이터에 대해서는 중복 항목 제거하라는 기능을
고급필터에서 사용가능하도록 되어 있는데 행으로 된 데이터에 대해서 중복항목을 제거하려면
위의 내용처럼 정말 수작업이 많이 필요합니다.

특히나 중복 항목이라는 것은 데이터의 위치가 필요 없고 그 데이터만 필요하고 내용 중 빈셀도
의미 없는 데이터이기 때문에 처리를 해서 없애 버리고 자료를 구하는 것이 일반적인 상식이라고
생각합니다. 그래서 제가 예전에 찾아 쓰던 모듈을 응용하여 함수를 만듭니다. 빈 셀도 자료라고
처리해야 할 필요가 있을 때는 if 문을 제거하시고 사용하시면 됩니다.
모듈을 하나 만드시고 아래 식을 붙여 넣습니다.

Option Explicit

Function UniqItemRng(SelRng As Range) As String

Dim AllCells As Range, Cell As Range
Dim NoDupes As New Collection

Dim i As Integer, j As Integer
Dim Swap1, Swap2, item
Dim UniqStr As String

Set AllCells = SelRng

On Error Resume Next

For Each Cell In AllCells

If Len(Cell.Value) > 0 Then ‘ 빈셀을 포함시키지 않음
‘ Add method의 2번째 인자는 문자열이어야만 함
NoDupes.Add Cell.Value, CStr(Cell.Value)

End If

Next Cell

On Error GoTo 0

For i = 1 To NoDupes.Count – 1

For j = i + 1 To NoDupes.Count

If NoDupes(i) > NoDupes(j) Then

Swap1 = NoDupes(i)
Swap2 = NoDupes(j)

NoDupes.Add Swap1, before:=j
NoDupes.Add Swap2, before:=i
NoDupes.Remove i + 1
NoDupes.Remove j + 1

End If

Next j

Next i

For Each item In NoDupes

UniqStr = UniqStr & “:” & item

Next item

UniqItemRng = UniqStr

Set Cell = Nothing

End Function

위 내용은 이해하실 필요는 없고 해석을 하자면 가로나 세로 영역이 선택되면 그 영역의 내용을
중복 항목을 제거하고 자료를 정렬해서 UniqStr이라는 변수에 차곡차곡 붙여 넣는 것입니다.
중간에 구분자(“:”)가 중요한 역할을 합니다. 제가 올린 팁에서 보시면 왜 넣었는지 이해하실
것입니다. “:”는 임의로 넣은 문자이니 엑셀 자료에서 잘 사용하지 않는 문자열로 대치하십시오.

이렇게 하면 상기의 스샷과 같이 특정 셀에서 =UniqItemRng라고 하시면 일반 엑셀 내장함수와
같이 영역을 선택하라고 하면 영역을 선택해주면 해당 셀에 중복자료를 표시해 줍니다. 다른
엑셀 시트에서 사용하시려면 .xla로 추가해서 사용하세요. 추가하는 방법은 구걸하세요 ^^;;;

그 다음 버튼 하나 만드시고 아래 서브 루틴을 버튼에 연결하시면 =UniqItemRng 함수가 사용된
셀의 오른쪽에 중복 항목들이 주르륵 나타납니다. 위의 매크로처럼 왼쪽 전체를 지우고 처리할 수도
있겠지만 그냥 예시로 나타내었으니 알아서 수정해서 사용하세요.

Private Sub CommandButton1_Click()

Dim TempStr As String
Dim RngStr As String

Dim intNum As Integer
Dim NumCnt As Integer

Dim RngCel As Range
Dim RngRef As Range

NumCnt = 0
TempStr = “”

‘ 검색할 셀의 조건을 셀을 클릭해서 선택
Set RngRef = Application.InputBox(“셀 선택”, , Type:=8)

‘ 속도를 위하여 스크린 업데이트 하지 않음
Application.ScreenUpdating = False

‘ 검색할 영역에서 선택된 셀과 같은 조건이 있으면 카운트
For Each RngCel In RngRef

RngStr = RngCel.Text

For intNum = 1 To Len(RngStr)
If Mid(RngStr, intNum, 1) <> “:” Then
TempStr = TempStr + Mid(RngStr, intNum, 1)

RngCel.Offset(0, NumCnt).Value = TempStr

Else
‘ 열의 위치 수정
NumCnt = NumCnt + 1
‘ 임시 문자열 초기화
TempStr = “”

End If

Next intNum

‘ 열의 위치 리셋
NumCnt = 0

Next

‘ 스크린 업데이트 진행
Application.ScreenUpdating = True

End Sub

위 내용을 보시면 간단하지만 이 영역을 자동화하려는 시도를 많이 해봤는데 더 복잡할 것 같고
엑셀의 내장함수의 고급 필터와 같은 방법으로 영역 선택해서 같은 행의 위치에 중복 데이터를
출력하도록 만들었습니다. 물론 코드 하나 더 넣어서 출력 위치도 선택할 수 있지만 크게 의미가
있을 것 같지 않아서 기능을 넣지 않았습니다.

하나의 문제를 보고 해결하는데 많은 고민을 하고 시행착오도 많이 겪습니다. 이런 아이디어가
괜찮을까? 저런 아이디어가 괜찮을까? 이 팁을 읽고 실무에서 잘 사용하도록 코드를 간결하게
만들어야지하면서 업무 중간 중간에 생각날 때마다 코드 작성해서 실행하고 무지 막지한 에러!
가끔씩 무한루프에 빠져 저장안한 코드 다 날아가고 … 여튼 재미있는 작업들입니다.

첨부 화일 : 20150902-일정 영역에서 행별 중복항목 제거 및 추출 방법

By vinipapa • 무른모 • 0 • Tags: 엑셀, 중복제거, 팁, 행별 중복항목

«< 29 30 31 32 33 >»

카테고리

  • 매킨토시 (261)
    • 굳은모 (73)
    • 무른모 (194)
  • 빈이네 (304)
    • 가족들 (108)
    • 까만콩 (60)
    • 엄마아빠 (131)
  • 잡동사니 (175)
    • 수다떨기 (37)
    • 정 보 (127)
    • 책읽기 (11)

그 밖의 기능

  • 로그인
  • 글 RSS
  • 댓글 RSS
  • WordPress.org

태그

AirPlay AirPrint Apple BootCamp bundle Database Design Dock Dropbox Edit Event Excel free iPad iPhone iTunes Limitted Free Mac Macbook Mac Bundle MacJournal Mac OSX Macupdate MobileMe OCR Pebble safari Sale share Snow Leopard software Tip tweet Twitter Update Windows 구입 나들이 맥 무료 빈이 업데이트 엑셀 엑셀(EXCEL) 팁
  • 29년 11개월 회사를 그만 두면서…
  • 2024 윤석열 탄핵 집회 참석
  • 맥 마이그레이션 중…
  • 동백
  • 같은 나무에 다른 색 잎 들

↑

© ::: 까만콩 빈이네 ::: 2026
Powered by WordPress • Themify WordPress Themes