
Tenho dados no Excel parecidos com estes:
column1 column2 column3, column4, column5
Company1 email1 email2 email3
Company2 email1 email2
Company3 email1 email2 email3 email4 email5
Tenho cerca de 25 mil linhas desses dados, talvez 25 mil empresas e 40 mil endereços de e-mail. Eu gostaria que os dados ficassem assim:
Company1 email1
Company1 email2
Company1 email3
Company2 email1
etc.
Responder1
Salve o arquivo csv e use awk
(ferramenta linux ou cygwin):
awk -F, '{if (NR>1) {if (NF==1) {print $1} else {for (f=2; f<=NF; f++) print $1","$f}}}' ./myfile.csv >./mynewfile.csv
Explicação:
awk
lê o arquivo linha por linha, divide cada linha em 'campos' (ou seja, colunas) usando a vírgula como delimitador ( -F
,), cada campo é chamado $1
. Ele pula a primeira linha (cabeçalhos) e, para cada linha, cria uma série de linhas onde cada campo está em uma linha separada precedida pelo primeiro campo. A saída é gravada em um novo arquivo. Você pode abrir este novo arquivo no Excel.
Responder2
Esta macro fará o trabalho:
Public Sub createrows()
Application.ScreenUpdating = False
Dim wks As Worksheet
Set wks = ActiveSheet
firstrow = 2
thecolumn = 3
searchingrow = True
therow = firstrow
While searchingrow
totalcolumns = wks.Cells(therow, Columns.Count).End(xlToLeft).Column
For j = totalcolumns To thecolumn Step -1
a = wks.Cells(therow, j)
Rows(therow + 1).Insert shift:=xlShiftDown
wks.Cells(therow + 1, 1) = wks.Cells(therow, 1)
wks.Cells(therow + 1, 2) = wks.Cells(therow, j)
Next j
therow = therow + 1
If wks.Cells(therow, 1) = "" Then searchingrow = False
Wend
wks.Range(Cells(1, thecolumn), Cells(therow, 1000)).Delete
Application.ScreenUpdating = True
themessage = MsgBox("Finished", vbInformation)
End Sub
Abra VBA/Macro com ALT+F11, insira um novo módulo emEsta pasta de trabalhoe cole o código no lado direito. Execute a macro.
Responder3
Você não pode fazer isso diretamente no Excel. Sua melhor opção é ter um pequeno programa/script fazendo a conversão para você. Proponho a você uma resposta que usaPitão.
- Baixe e instale o python se ainda não o tiver instalado em seu computador.
- No Excel, salve seu arquivo como CSV.
Observação:Pode haver mais de uma opção CSV na caixa de diálogo Salvar como. Certifique-se de escolherCSV (delimitado por vírgula). - Copie o código abaixo no bloco de notas e salve-o como arquivo
convert.py
. Você terá que escolherTodos os arquivospara que o Bloco de notas salve com a extensão de arquivo correta.
Lembre-se de substituir"c:/users/user/desktop/book1.csv"
e"c:/users/user/desktop/book2.csv"
pelos nomes corretos dos arquivos de entrada e saída, respectivamente. Além disso, você deve alterar todas as barras invertidas (\
) por barras (/
).
infile = open("c:/users/user/desktop/book1.csv", "rb")
outfile = open("c:/users/user/desktop/book2.csv", "wb")
import csv
reader = csv.reader(infile)
writer = csv.writer(outfile)
reader.next() # skip header
writer.writerow(["Company", "Email"])
writer.writerows(((row[0], email) for row in reader \
for email in row[1:] if email != ""))
outfile.close()
infile.close()
- Clique duas vezes no arquivo python para executá-lo e realizar a conversão.
Responder4
Aqui está outra macro VBA que deve ser executada de forma relativamente rápida, pois funciona em arrays VBA, e não na planilha.
Ele assume que os dados de origem começam em A1 ou A2; a região de dados é contígua e os emails de cada empresa são contíguos (de modo que a primeira célula em branco na linha fique após o último endereço de email). O código exigiria pequenas modificações se alguma dessas suposições não fosse verdadeira.
Também existe a suposição de que não há rótulos de coluna, com instruções nos comentários do código sobre como compensar isso.
Option Explicit
Sub RowsToColumns()
Dim vSrc As Variant
Dim COL As Collection
Dim wsSrc As Worksheet, wsRes As Worksheet, rRes As Range
Dim S(0 To 1) As String
Dim I As Long, J As Long
'Define source and result worksheets and ranges
'Alter as necessary
Set wsSrc = Worksheets("sheet3")
Set wsRes = Worksheets("sheet4")
Set rRes = wsRes.Cells(1, 1)
'Read source data into array
' This method assumes data starts in A2, and is
' contained in a contiguous array.
'But other methods could be used
vSrc = wsSrc.Cells(2, 1).CurrentRegion
'Collect the results into Collection object
'Assumes no header row, if there is, then start
' with for I = 2 to ...
Set COL = New Collection
For I = 1 To UBound(vSrc, 1) 'the rows
For J = 2 To UBound(vSrc, 2) 'the columns
S(0) = vSrc(I, 1) 'company name
S(1) = vSrc(I, J) 'email
If S(1) <> "" Then
COL.Add S
Else
Exit For 'assumes first blank in email list is end of list
End If
Next J
Next I
'Create results array
ReDim vres(1 To COL.Count, 1 To 2)
For I = 1 To COL.Count
With COL(I)
vres(I, 1) = COL(I)(0)
vres(I, 2) = COL(I)(1)
End With
Next I
'Write the results to worksheet
Set rRes = rRes.Resize(rowsize:=UBound(vres, 1), columnsize:=UBound(vres, 2))
With rRes
.EntireColumn.Clear
.Value = vres
.EntireColumn.AutoFit
End With
End Sub