Что нового

[Массивы] Удаление дубликатов строк в файле Excel

atmel007

Новичок
Сообщения
13
Репутация
0
Здравствуйте,
скрипт создает файл excel, сортирует его...
Как найти и удалить точные дубликаты строк в открытом excel?
Код:
Номер:	12345	Дата:	12.02.2013 10:24	Длительность:	0	Комментарий:	текст1
Номер:	12456	Дата:	12.02.2013 10:50	Длительность:	0	Комментарий:	текст
Номер:	12347	Дата:	12.02.2013 10:55	Длительность:	0	Комментарий:	текст
Номер:	545654	Дата:	12.02.2013 11:24	Длительность:	0	Комментарий:	текст
Номер:	12345	Дата:	12.02.2013 10:24	Длительность:	0	Комментарий:	текст1
Номер:	12347	Дата:	12.02.2013 10:55	Длительность:	0	Комментарий:	найден
в примере совпадение по 1 и 5 строке, т.е точное совпадение строки.
файл заполняется скриптом, после заполнения файла удалить дубликаты
все примеры нашел только для строк в txt файлах, для excel не нашел.
я так понял нужно загружать лист в массив обработать, залить из массива в excel
Код:
$avArray=_ExcelReadSheetToArray($oExcel,1,1, 1, 1)
_ExcelWriteSheetFromArray($oExcel, $avArray,1,1, 1, 1)
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
atmel007 [?]
все примеры нашел только для строк в txt файлах, для excel не нашел.
Есть функция удаления дубликатов в массиве (_ArrayUnique), или поищи по форуму _ArrayRemoveDuplicates.
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
atmel007
Как-то так:
Код:
#include <Excel.au3>
#include <Array.au3>

$sFilePath = @ScriptDir & '\Лист Microsoft Excel.xls'
$oExcel = _ExcelBookOpen($sFilePath)

$aArrayA = _ExcelReadSheetToArrayQuick($oExcel, 1, 1) ; чтение в excel

Dim $aArrayB[UBound($aArrayA)]
$iN = UBound($aArrayA, 2)
$sTring = ''

For $i = 0 To UBound($aArrayA) - 1
	For $j = 0 To UBound($aArrayA, 2) - 1
		$sTring &= $aArrayA[$i][$j] & '##'
	Next
	$aArrayB[$i] = $sTring
	$sTring = ''
Next

$aArrayB = _ArrayUnique($aArrayB)
_ArrayDelete($aArrayB, 0)

Dim $aArrayA[UBound($aArrayB)][$iN]

For $i = 0 To UBound($aArrayB) - 1
	$aArrayC = StringSplit($aArrayB[$i], '##', 1)
	For $j = 1 To $iN
		$aArrayA[$i][$j - 1] = $aArrayC[$j]
	Next
Next

_ArrayDisplay($aArrayA)

;_ExcelSheetWriteFromArray($oExcel, $aArrayA, 1, 1) ; запись в excel


Func _ExcelReadSheetToArrayQuick($oExcel, $iStartRow = 1, $iStartColumn = 1, $iRowCnt = 0, $iColCnt = 0)
	Local $avRET[1][2] = [[0, 0]] ; 2D return array
	; Test inputs
	If Not IsObj($oExcel) Then Return SetError(1, 0, 0)
	If $iStartRow < 1 Then Return SetError(2, 0, 0)
	If $iStartColumn < 1 Then Return SetError(2, 1, 0)
	If $iRowCnt < 0 Then Return SetError(3, 0, 0)
	If $iColCnt < 0 Then Return SetError(3, 1, 0)

	; Get size of current sheet as R1C1 string
	;     Note: $xlCellTypeLastCell and $x1R1C1 are constants declared in ExcelCOM_UDF.au3
	Local $sLastCell = $oExcel.Application.Selection.SpecialCells($xlCellTypeLastCell).Address(True, True, $xlR1C1)

	; Extract integer last row and col
	$sLastCell = StringRegExp($sLastCell, "\A[^0-9]*(\d+)[^0-9]*(\d+)\Z", 3)
	Local $iLastRow = $sLastCell[0]
	Local $iLastColumn = $sLastCell[1]

	; Return 0's if the sheet is blank
	If $sLastCell = "R1C1" And $oExcel.Activesheet.Cells($iLastRow, $iLastColumn).Value = "" Then Return $avRET

	; Check input range is in bounds
	If $iStartRow > $iLastRow Then Return SetError(2, 0, 0)
	If $iStartColumn > $iLastColumn Then Return SetError(2, 1, 0)
	If $iStartRow + $iRowCnt - 1 > $iLastRow Then Return SetError(3, 0, 0)
	If $iStartColumn + $iColCnt - 1 > $iLastColumn Then Return SetError(3, 1, 0)

	; Check for defaulted counts
	If $iRowCnt = 0 Then $iRowCnt = $iLastRow - $iStartRow + 1
	If $iColCnt = 0 Then $iColCnt = $iLastColumn - $iStartColumn + 1

	; Size the return array
	ReDim $avRET[$iRowCnt][$iColCnt]
	;$avRET[0][0] = $iRowCnt
	;$avRET[0][1] = $iColCnt
	$avRET = $oExcel.Application.WorksheetFunction.Transpose($oExcel.Activesheet.Cells($iStartRow, $iStartColumn).Resize($iRowCnt, $iColCnt).Value) ; здесь происходит считывание целым массивом, а не по элементно
	;Return data
	Return $avRET
EndFunc   ;==>_ExcelReadSheetToArrayQuick

Func _ExcelSheetWriteFromArray($oExcel, ByRef $aArray, $iExcelStartRow = Default, $iExcelStartCol = Default, $iArrayStartRow = Default, $iArrayStartCol = Default, $iArrayEndRow = Default, $iArrayEndCol = Default)
	Local $iExcelEndRow = 1
	Local $iExcelEndCol = 1

	If Not IsObj($oExcel) Then Return SetError(1, 0, 0)
	If UBound($aArray, 0) <> 2 Then Return SetError(2, 0, 0)
	If $iExcelStartRow = Default Then $iExcelStartRow = 1
	If $iExcelStartCol = Default Then $iExcelStartCol = 1
	If $iArrayStartRow = Default Then $iArrayStartRow = 0
	If $iArrayStartCol = Default Then $iArrayStartCol = 0
	If $iArrayEndRow = Default Then $iArrayEndRow = UBound($aArray) - 1
	If $iArrayEndCol = Default Then $iArrayEndCol = UBound($aArray, 2) - 1
	If $iExcelStartRow < 1 Then $iExcelStartRow = 1
	If $iExcelStartCol < 1 Then $iExcelStartCol = 1
	If $iArrayStartRow < 0 Then $iArrayStartRow = 0
	If $iArrayStartCol < 0 Then $iArrayStartCol = 0
	If $iArrayEndRow < $iArrayStartRow Then Return SetError(3, 1, 0)
	If $iArrayEndCol < $iArrayStartCol Then Return SetError(4, 1, 0)
	$iExcelEndRow = $iExcelStartRow + $iArrayEndRow - $iArrayStartRow
	$iExcelEndCol = $iExcelStartCol + $iArrayEndCol - $iArrayStartCol

	; Check if only part of the array is to written to the speadsheet
	If $iArrayStartRow <> 0 Or $iArrayStartCol <> 0 Or $iArrayEndRow <> UBound($aArray) - 1 Or $iArrayEndCol = UBound($aArray, 2) - 1 Then
		;Copy specified array range to a temporary array
		Local $aTemp[$iArrayEndRow - $iArrayStartRow + 1][$iArrayEndCol - $iArrayStartCol + 1]
		Local $iRow = 0
		Local $iCol = 0
		For $i = $iArrayStartRow To $iArrayEndRow
			$iCol = 0
			For $j = $iArrayStartCol To $iArrayEndCol
				$aTemp[$iRow][$iCol] = $aArray[$i][$j]
				$iCol += 1
			Next
			$iRow += 1
		Next
		With $oExcel.ActiveSheet
			.Range(.Cells($iExcelStartRow, $iExcelStartCol), .Cells($iExcelEndRow, $iExcelEndCol)).Select
			.Range(.Cells($iExcelStartRow, $iExcelStartCol), .Cells($iExcelEndRow, $iExcelEndCol)).value = $oExcel.Application.WorksheetFunction.Transpose($aTemp)
		EndWith
	Else
		With $oExcel.ActiveSheet
			.Range(.Cells($iExcelStartRow, $iExcelStartCol), .Cells($iExcelEndRow, $iExcelEndCol)).Select
			.Range(.Cells($iExcelStartRow, $iExcelStartCol), .Cells($iExcelEndRow, $iExcelEndCol)).value = $oExcel.Application.WorksheetFunction.Transpose($aArray)
		EndWith
	EndIf
EndFunc   ;==>_ExcelSheetWriteFromArray

Правда, использованы нестандартные функции чтения-записи массива, они быстрее. И, возможно, будут проблемы с типами данных.
 
Автор
A

atmel007

Новичок
Сообщения
13
Репутация
0
вроде то что нужно,а скажите уже при считывании массива данные типа: 12.02.2013 10:24 превращаются в 20130212102428 я так понимаю это в шаблоне поиска задается
Код:
$sLastCell = StringRegExp($sLastCell, "\A[^0-9]*(\d+)[^0-9]*(\d+)\Z", 3)
?
http://autoit-script.ru/index.php/topic,4901.0.html
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
atmel007,
Предупреждение За нарушение общих правил (пункт В.4):
Не лепите несколько вопросов разной тематики в один пост. По типу "Ребят, а ещё такой вопрос...". Каждый вопрос в свою тему.


С уважением, ваш Глобальный модератор.
 
Верх