2022년 1월 24일 월요일

Python 으로 텍스트 인코딩 정보 확인하기 (Python3, 파이썬3)

윈도우에서 파이썬을 사용하다보면 텍스트 파일 (csv) 등을 읽을 때 인코딩 이슈가 자주 있다. 판다스로 csv 파일을 읽어올 때 인코딩 타입을 지정해줘야 하는데, 가끔 쓰는 툴 마다 인코딩이 달라서 에러가 발생한다. 예를 들어 MS Office Excel 은 euc-kr (cp949 로 읽을 수 있다.) 인데, 파이썬은 UTF-8 이고, 언리얼은 한글 포함된 문서 한정으로 UTF-16 이고 아닐 때는 UTF-8 이다. 판다스로 읽을 때 아래와 같이 인코딩 타입을 꼭 지정해줘야 하는데, 입력되는 소스의 인코딩이 제각각일 때는 약간 피곤하다. Notepad++ 로 읽어서 인코딩 바꿔주는것은 어렵진 않지만 많은 양을 매번 바꿀 때는 번거롭다.

data = pd.read_csv('targetFileName', delimiter=',', encoding='cp949', engine='python') #인코딩타입은 꼭 바꿔주야 한다.
그래서 귀찮을 때 나를 도와주는 파이썬에게 부탁하여 해결해보았다. 아래 코드를 사용한다.

import chardet
#import sys

# 윈도우 환경에서 cp949 텍스트 인코딩 때문에 발생하는 문제를 우회하기 위한 코드이다.

# 아래는 만일을 위해 출력하는 것 
#print(sys.stdin.encoding) #인풋 인코딩 타입
#print(sys.stdout.encoding) #아웃풋 인코딩 타입

file = ".\\확인할대상.csv" #csv 나 txt 등 텍스트 파일의 인코딩 타입을 확인하고 싶은 것의 경로를 입력한다.

def getDetectEncoding(file) :

    try:
        print("Fast Detect!!!")
        with open(file, 'r') as f:
            file_data = f.readlines() #텍스트로 읽어본다. 잘 읽히면 문제 없다. 보통 cp949 에러가 발생한다.
            f.close()
            #print(chardet.detect(file_data))
        return chardet.detect(file_data[1])['encoding'] #0번째 줄은 보통 컬럼 헤더로 정보고 1번째 줄이 실제 내용이다. 빠른 처리를 위해 1줄만 읽어본다.
    
    except:
        print ("Except!!! not UTF-8 or 16. Retry Now... ")
        with open(file, 'rb') as f:
            file_data = f.read() #cp949 에러가 발생했을 때는 그냥 파일을 바이너리로 통채로 읽는다. 용량이 클 수록 느려진다. 하지만 쉽게 해결하는 방법
            f.close()
    
    #print(chardet.detect(file_data))
    return chardet.detect(file_data)['encoding']

print(getDetectEncoding(file))
여기까지이고, 만일 판다스에서 인코딩을 자동으로 하게하려면 리턴되는 스트링을 encoiding에 바인딩 시키면 된다. 끝!! 파이썬 3.9 기준이다.

2020년 2월 7일 금요일

VBS 로 Excel Macro (Sub) 실행하기. Excel 백그라운드 매크로 실행

엑셀을 실행하지 않고 (백그라운드에서 실행하여) 매크로를 실행해주는 방법입니다.
VBS 를 사용합니다. (Visual Basic Script)

새 텍스트 파일을 만들어 확장자를 .vbs 로 변경해주시고 아래의 코드를 붙여넣어보세요.
엑셀 파일은 .xlsm 으로 미리 모듈 등으로 Sub문 매크로를 만들어두셔야 합니다.
VBS 파일의 경로는 xlsm과 같은 경로에 만듭니다.

이걸로 엑셀을 실행해서 작업을 하지 않아 더 빠르게 작업을 해둘 수 있어요.
적당히 응용해서 사용해보세요.


Dim Excel, Path

Set Excel = WScript.createObject("Excel.Application")

Path = WScript.ScriptFullName             ' 현재 실행하는 전체 파일이름 (경로+이름)
Path = Left(Path, InStrRev(Path, "\"))  ' 이름제거후 경로만 추출

Excel.Workbooks.Open(Path&"엑셀파일이름.xlsm") '매크로 포함된 엑셀 파일 실행

'실행하고 싶은 Sub문 입력
'Sub문에 모든걸 해두고 그 함수를 호출하는 것이 순차적으로 처리되어 원하는 결과물이 나올 것입니다.
'순차적으로 Excel.Run 을 시키면 동시에 실행되서 이상한 결과가 나올 수 있어요.
'이 함수에서 처리가 끝난 후, 해당 Workbook 을 저장하기를 권합니다.
Excel.Run "Sub문 매크로 함수명" 

' 파일 닫기
Excel.Quit

'변수 초기화
Set Excel = Nothing
Set Path = Nothing

2020년 2월 6일 목요일

Python 폴더 내 모든 wav 파일의 length를 가져와 모두 합치기 (duration 초 누산)

python 3.6.6 에서 확인했습니다.
wave 파일을 읽어서 frame수 / rate를 하면 길이가 sec으로 나옵니다.



#path_dir에 wav파일만 있다고 가정합니다.
#path_dir 에 있는 모든 파일을 읽어서 list에 넣고 length(duration)을 모두 더합니다.

import wave
import contextlib
import os
#import sys

path_dir = '드라이브:/경로/경로/' #경로 끝에 / 꼭 붙이기
file_list =os.listdir(path_dir) #경로 읽어 파일명 리스트 만들기
file_list.sort() #정렬

# 누적값 초기화
acc = 0

for i in file_list:

 with contextlib.closing(wave.open(path_dir + i,'r')) as f:
  frames = f.getnframes()
  rate = f.getframerate()
  duration = frames / float(rate)
  #print(duration)
  acc += duration #누적값

#결과 출력
print (acc)

2020년 1월 29일 수요일

Excel VBA 엑셀 파일 경로 값 가져오기 File Location

엑셀 파일 경로 값 가져오기


Function getCellValue(LOC_, strFile , strSheet , strPath )
'파일을 여는 것 따로 해줘야 하는데, 열었다 닫았다 prcess 과부하가 걸릴 수 있으므로 주의

    Dim strPath, strFile, strSheet, strRng, strRef, Result As String

    strPath = PathName_ 
    strFile = FileName_
    strSheet = SheetName_
    'strRng = Range(LOC_).Value
    strRng = LOC_

    strRef = "'" & strPath & "[" & strFile & "]" & strSheet & "'!" & strRng
    'Debug.Print (strRef)
    getCellValue = Range(strRef).Value
End Function



끝.

2019년 9월 11일 수요일

Excel Vba Sheet 내용을 Text 파일로 저장하기 (UTF-8)

시트의 내용을 텍스트 파일로 저장하기. (UTF-8 대응)
Sub SheetToText()

    Dim streamWrite As New ADODB.Stream '// 쓰기 스트림 선언 Microsoft ADODB 6.1 (ActiveX) 참조 필수
    Dim sText       As Variant          '// 파일 데이터 선언

    
    '// 파일 쓰기
    streamWrite.Type = adTypeText
    streamWrite.Charset = "UTF-8"
    streamWrite.Open
    
    '// 첫줄에 넣을 메시지
    streamWrite.WriteText "// 첫줄"
    
    '//시트 데이터 읽는데 필요한 변수 선언
    Dim rng As Range
    Dim iRow As Long, iCol As Integer
    Dim sTxt As String, sPath As String, deLimiter As String
    Set rng = ActiveSheet.UsedRange

    deLimiter = ", "     '// 구분자 "," 입력 바꿔도 됨

    For iRow = 1 To rng.Rows.Count  '// 1행부터 마지막 행까지
        For iCol = 1 To rng.Columns.Count  '// 1열부터 오른쪽 최대 열까지
            sTxt = sTxt & ActiveSheet.Cells(iRow, iCol).Value & deLimiter
        Next iCol
        streamWrite.WriteText (Left(sTxt, Len(sTxt) - 1) & vbLf)

       sTxt = vbNullString
    Next iRow
    
    
    '// 스트림의 마지막 표시
    streamWrite.SetEOS
    
    '// 세이브
    Call streamWrite.SaveToFile(Application.ActiveWorkbook.Path + "\" + ActiveSheet.Name + ".txt", adSaveCreateOverWrite) '//저장할 경로와 파일 이름은 필요에 따라 변경할 것
    
    '// 스트림 클로즈
    streamWrite.Close
    
End Sub

EXCEL VBA로 euc-kr -> utf-8로 변경하는 코드

EXCEL VBA로 텍스트 쓸 때 이미 써진 파일을 euc-kr -> utf-8 로 수정하는 코드
'Microsoft ActiveX Data Objects 6.1 Library 참조 필요

Private Sub EuckrToUtf8NoBOM(a_sFrom, a_sTo)

    Dim streamRead  As New ADODB.Stream '// 읽을 데이터
    Dim streamWrite As New ADODB.Stream '// 작성할 데이터
    Dim sText       As Variant          '// 파일 데이터
    
    '// 파일데이터
    streamRead.Type = adTypeText
    streamRead.Charset = "euc-kr" '여기에 한글형을 입력한다.
    streamRead.Open
    Call streamRead.LoadFromFile(a_sFrom)
    
    '// 개행코드 CRLF를 LF로 변환
    sText = streamRead.ReadText
    sText = Replace(sText, vbCrLf, vbLf)
    
    '// 파일쓰기
    streamWrite.Type = adTypeText
    streamWrite.Charset = "UTF-8"
    streamWrite.Open
    
    '// euc-kr 을 utf-8 데이터로 쓴다.
    Call streamWrite.WriteText(sText)
    
    '// 바이너리 모드로 쓴 데이터 시작 위치를 BOM분의 3바이트씩 민다.
    streamWrite.Position = 0
    streamWrite.Type = adTypeBinary
    streamWrite.Position = 3
    
    '// 3바이트 민 상태에서 데이터를 취득
    sText = streamWrite.Read
    
    '// 3바이트 민 위치를 원래대로 돌린다.
    streamWrite.Position = 0
    
    '// BOM이 제거된 데이터를 처음부터 다시 쓴다.
    Call streamWrite.Write(sText)
    
    '// 현시점의 말미를 끝으로, 직전에 쓴 3바이트를 데이터 대상외로 한다.
    streamWrite.SetEOS
    
    '// 저장
    Call streamWrite.SaveToFile(a_sTo, adSaveCreateOverWrite)
    
    '// 파일 닫기
    streamRead.Close
    streamWrite.Close
End Sub

EXCEL VBA 텍스트 파일 저장하기 (출력하기)

data 코드의 일부를 자동 생성해주는 스크립트 만들 때 유용하다.
Option Explicit

Sub Createtextfile()


Dim TF As Object
Dim TFT As Object

'만들기
Set TF = CreateObject("scripting.filesystemobject")
Set TFT = TF.Createtextfile(Application.ActiveWorkbook.Path + "\l10n.js")

'Debug.Print (Application.ActiveWorkbook.Path)

'내용넣기
TFT.WriteLine "this is just test file" & vbCr & "afs"
TFT.WriteLine "this is 2nd line of test file"
TFT.WriteLine ActiveSheet.Name

'닫기
TFT.Close
Set TF = Nothing
Set TFT = Nothing

End Sub