Что нового

[Данные, строки] Сравнение строк в столбцах в текстовом файле с разделителем - табуляция

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
Возможно извращение, но мой вариант используя Excel
После запуска постоянно считывает содержимое файла 1.txt и сравнивает его содержимое с файлом 2.txt, но не сначала, а только вновь добавленные строки, при перезаписи файла счётчик строк обнуляется и всё заново, результат пишет в консоль( пока для теста). Выход - кнопка "q"
Код:
#include <File.au3>
#include <Array.au3>
#include <Excel.au3>

Global $aArray1, $aArray2

HotKeySet('q', '_Stop')

Global $sFile1 = @ScriptDir & '\1.txt'
Global $sFile2 = @ScriptDir & '\2.txt'

Global $oExcel = _Excel_Open(False)
$hFile2 = _Excel_BookOpen($oExcel, $sFile2)
If @error Then MsgBox(48, '@error', @error)
$aArray2 = _Excel_RangeRead($hFile2)
_Excel_BookClose($hFile2)
If @error Then MsgBox(48, '@error', @error)

Global $iMaxIndex = 1

;_ArrayDisplay($aArray1)
While 1
	_Start()
	Sleep(20)
WEnd

Func _Start()
	$hFile1 = _Excel_BookOpen($oExcel, $sFile1)
	If @error Then MsgBox(48, '@error', @error)
	$aArray1 = _Excel_RangeRead($hFile1)
	_Excel_BookClose($hFile1)
	If @error Then MsgBox(48, '@error', @error)
	$MaxArray1 = UBound($aArray1) - 1
	If $MaxArray1 > 0 Then
		If $iMaxIndex > $MaxArray1 Then;Если файл 1 начат заново и переписан файл 2
			$iMaxIndex = 1
			$hFile2 = _Excel_BookOpen($oExcel, $sFile2)
			If @error Then MsgBox(48, '@error', @error)
			$aArray2 = _Excel_RangeRead($hFile2)
			_Excel_BookClose($hFile2)
			If @error Then MsgBox(48, '@error', @error)
		EndIf

		For $i = $iMaxIndex To $MaxArray1
			If $iMaxIndex < $i Then $iMaxIndex = $i
			If $aArray1[$i][3] <> 'N/A' And $aArray1[$i][3] = $aArray2[$i][3] / 2 And $aArray1[$i][9] < 300000 Then
				ConsoleWrite($aArray1[$i][1] & @CRLF)
			EndIf
		Next
	EndIf
EndFunc   ;==>_Start

Func _Stop()
	_Excel_Close($oExcel)
	Exit
EndFunc   ;==>_Stop
Из минусов, то , что хоть файл 1.txt сравнивает только "свежие" строки, но он перезаписывается в массив всё время весь целиком.
Но при этом считывание файла в массив при помощи Excel гораздо быстрее, чем читать текстовый файл построчно.
 
Автор
D

Dk

Новичок
Сообщения
358
Репутация
2
Re:Сравнение строк в столбцах в текстовом файле с разделителем - табуляция

ra4o сказал(а):
Возможно извращение, но мой вариант используя Excel
После запуска постоянно считывает содержимое файла 1.txt и сравнивает его содержимое с файлом 2.txt, но не сначала, а только вновь добавленные строки, при перезаписи файла счётчик строк обнуляется и всё заново, результат пишет в консоль( пока для теста). Выход - кнопка "q"
Код:
#include <File.au3>
#include <Array.au3>
#include <Excel.au3>

Global $aArray1, $aArray2

HotKeySet('q', '_Stop')

Global $sFile1 = @ScriptDir & '\1.txt'
Global $sFile2 = @ScriptDir & '\2.txt'

Global $oExcel = _Excel_Open(False)
$hFile2 = _Excel_BookOpen($oExcel, $sFile2)
If @error Then MsgBox(48, '@error', @error)
$aArray2 = _Excel_RangeRead($hFile2)
_Excel_BookClose($hFile2)
If @error Then MsgBox(48, '@error', @error)

Global $iMaxIndex = 1

;_ArrayDisplay($aArray1)
While 1
	_Start()
	Sleep(20)
WEnd

Func _Start()
	$hFile1 = _Excel_BookOpen($oExcel, $sFile1)
	If @error Then MsgBox(48, '@error', @error)
	$aArray1 = _Excel_RangeRead($hFile1)
	_Excel_BookClose($hFile1)
	If @error Then MsgBox(48, '@error', @error)
	$MaxArray1 = UBound($aArray1) - 1
	If $MaxArray1 > 0 Then
		If $iMaxIndex > $MaxArray1 Then;Если файл 1 начат заново и переписан файл 2
			$iMaxIndex = 1
			$hFile2 = _Excel_BookOpen($oExcel, $sFile2)
			If @error Then MsgBox(48, '@error', @error)
			$aArray2 = _Excel_RangeRead($hFile2)
			_Excel_BookClose($hFile2)
			If @error Then MsgBox(48, '@error', @error)
		EndIf

		For $i = $iMaxIndex To $MaxArray1
			If $iMaxIndex < $i Then $iMaxIndex = $i
			If $aArray1[$i][3] <> 'N/A' And $aArray1[$i][3] = $aArray2[$i][3] / 2 And $aArray1[$i][9] < 300000 Then
				ConsoleWrite($aArray1[$i][1] & @CRLF)
			EndIf
		Next
	EndIf
EndFunc   ;==>_Start

Func _Stop()
	_Excel_Close($oExcel)
	Exit
EndFunc   ;==>_Stop
Из минусов, то , что хоть файл 1.txt сравнивает только "свежие" строки, но он перезаписывается в массив всё время весь целиком.
Но при этом считывание файла в массив при помощи Excel гораздо быстрее, чем читать текстовый файл построчно.

Спасибо за Ваш вариант.
Ещё пока нет времени протестировать его.
Но посути там всё правильно.

Но мне всё же нужно именно работа без excel. Я буду в дальнейшем дописывать разные примочки. В Вашем варианте у меня получается будет задействовано аж 3 программы. Excel, сам скрипт, и программа которая ведёт записи. В дальнейшем это будет неудобно.

Через 24 часа оставлю благодарность) :ok:
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
Вам не нужно открывать или производить какие либо действия с Excel, достаточно, что-бы он был просто установлен в системе, процесс считывания в массив происходит в фоне. Дальнейшую работу с данными выполнять из массива. Пробовал файлы в двумерный массив читать функцией "_FileReadToArray", но что-то у меня не получалось :(
 
Автор
D

Dk

Новичок
Сообщения
358
Репутация
2
Re: Сравнение строк в столбцах в текстовом файле с разделителем - табуляция

ra4o сказал(а):
Вам не нужно открывать или производить какие либо действия с Excel, достаточно, что-бы он был просто установлен в системе, процесс считывания в массив происходит в фоне. Дальнейшую работу с данными выполнять из массива. Пробовал файлы в двумерный массив читать функцией "_FileReadToArray", но что-то у меня не получалось :(


К сожалению у меня ничего не происходит.
А с файлами которые работают с программой, всегда выдаёт MsgBox"Error 4"
К сожалению Excel для меня не вариант.

Просто пример если даже открыть файл с помощью Excel, а потом сохранить его (ничего не меняв) он сохранит тхт-формат, но уже в другом виде...
Для меня слишком не понятно, я даже не знаю где искать причину, с функциями от ексцел у менай вообще нет никакого опыта.
Если сможете напишите пожалуйста по возможности без excel.
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
А вот так, без Excel ? Получилось прочесть в массив массивов...
Код:
#include <File.au3>
#include <Array.au3>

HotKeySet('q', '_Stop')
HotKeySet('й', '_Stop')

Global $sFile1 = @ScriptDir & '\1.txt'
Global $sFile2 = @ScriptDir & '\2.txt'
Global $aArray1, $aArray2, $iMaxIndex = 1

_FileReadToArray($sFile2, $aArray2, 2, @TAB)
If @error Then MsgBox(48, 'File2 error', @error)
_FileReadToArray($sFile1, $aArray1, 2, @TAB)
If @error Then MsgBox(48, 'File1 error', @error)

While 1

	Local $iArray1Size = _FileCountLines($sFile1)-1

	If $iMaxIndex > $iArray1Size Then _NewFile()

	If $iMaxIndex < $iArray1Size Then
		_FileReadToArray($sFile1, $aArray1, 2, @TAB)
		For $i = $iMaxIndex To $iArray1Size

			If ($aArray1[$i])[3] <> 'N/A' And ($aArray1[$i])[3] = ($aArray2[$i])[3] / 2 And ($aArray1[$i])[9] < 300000 Then
				ConsoleWrite(($aArray1[$i])[1] & @CRLF)
			EndIf

		Next
		$iMaxIndex = $iArray1Size
	EndIf

WEnd

Func _NewFile()
	$iMaxIndex = 1
_FileReadToArray($sFile2, $aArray2, 2, @TAB)
If @error Then MsgBox(48, 'File2 error', @error)
_FileReadToArray($sFile1, $aArray1, 2, @TAB)
If @error Then MsgBox(48, 'File1 error', @error)
EndFunc   ;==>_NewFile

Func _Stop()
	Exit
EndFunc   ;==>_Stop
Если в таком виде будет нормально работать, то вместо "ConsoleWrite" можно уже прицепить отправку почты итп.
 
Автор
D

Dk

Новичок
Сообщения
358
Репутация
2
Re: Сравнение строк в столбцах в текстовом файле с разделителем - табуляция

ra4o сказал(а):
А вот так, без Excel ? Получилось прочесть в массив массивов...
Код:
#include <File.au3>
#include <Array.au3>

HotKeySet('q', '_Stop')
HotKeySet('й', '_Stop')

Global $sFile1 = @ScriptDir & '\1.txt'
Global $sFile2 = @ScriptDir & '\2.txt'
Global $aArray1, $aArray2, $iMaxIndex = 1

_FileReadToArray($sFile2, $aArray2, 2, @TAB)
If @error Then MsgBox(48, 'File2 error', @error)
_FileReadToArray($sFile1, $aArray1, 2, @TAB)
If @error Then MsgBox(48, 'File1 error', @error)

While 1

	Local $iArray1Size = _FileCountLines($sFile1)-1

	If $iMaxIndex > $iArray1Size Then _NewFile()

	If $iMaxIndex < $iArray1Size Then
		_FileReadToArray($sFile1, $aArray1, 2, @TAB)
		For $i = $iMaxIndex To $iArray1Size

			If ($aArray1[$i])[3] <> 'N/A' And ($aArray1[$i])[3] = ($aArray2[$i])[3] / 2 And ($aArray1[$i])[9] < 300000 Then
				ConsoleWrite(($aArray1[$i])[1] & @CRLF)
			EndIf

		Next
		$iMaxIndex = $iArray1Size
	EndIf

WEnd

Func _NewFile()
	$iMaxIndex = 1
_FileReadToArray($sFile2, $aArray2, 2, @TAB)
If @error Then MsgBox(48, 'File2 error', @error)
_FileReadToArray($sFile1, $aArray1, 2, @TAB)
If @error Then MsgBox(48, 'File1 error', @error)
EndFunc   ;==>_NewFile

Func _Stop()
	Exit
EndFunc   ;==>_Stop
Если в таком виде будет нормально работать, то вместо "ConsoleWrite" можно уже прицепить отправку почты итп.

Да, супер, вроде всё работает :ok: :ok:
только здесь нужно было ConsoleWrite(($aArray1[$i])[0] & @CRLF), ноль за место 1.
Сейчас я потестю часик. Посмотрю, будут ли где ошибки. :scratch:


Добавлено:
Сообщение автоматически объединено:

ra4o сказал(а):
А вот так, без Excel ? Получилось прочесть в массив массивов...
Код:
#include <File.au3>
#include <Array.au3>

HotKeySet('q', '_Stop')
HotKeySet('й', '_Stop')

Global $sFile1 = @ScriptDir & '\1.txt'
Global $sFile2 = @ScriptDir & '\2.txt'
Global $aArray1, $aArray2, $iMaxIndex = 1

_FileReadToArray($sFile2, $aArray2, 2, @TAB)
If @error Then MsgBox(48, 'File2 error', @error)
_FileReadToArray($sFile1, $aArray1, 2, @TAB)
If @error Then MsgBox(48, 'File1 error', @error)

While 1

	Local $iArray1Size = _FileCountLines($sFile1)-1

	If $iMaxIndex > $iArray1Size Then _NewFile()

	If $iMaxIndex < $iArray1Size Then
		_FileReadToArray($sFile1, $aArray1, 2, @TAB)
		For $i = $iMaxIndex To $iArray1Size

			If ($aArray1[$i])[3] <> 'N/A' And ($aArray1[$i])[3] = ($aArray2[$i])[3] / 2 And ($aArray1[$i])[9] < 300000 Then
				ConsoleWrite(($aArray1[$i])[1] & @CRLF)
			EndIf

		Next
		$iMaxIndex = $iArray1Size
	EndIf

WEnd

Func _NewFile()
	$iMaxIndex = 1
_FileReadToArray($sFile2, $aArray2, 2, @TAB)
If @error Then MsgBox(48, 'File2 error', @error)
_FileReadToArray($sFile1, $aArray1, 2, @TAB)
If @error Then MsgBox(48, 'File1 error', @error)
EndFunc   ;==>_NewFile

Func _Stop()
	Exit
EndFunc   ;==>_Stop
Если в таком виде будет нормально работать, то вместо "ConsoleWrite" можно уже прицепить отправку почты итп.

К сожалению работает не корректно.
Всегда указывает одни и те же места-строки. Несмотря на то что, они абсолютно одинаковые. И когда скрипт идёт на второй заход, он опять показывает те же строки.
Скачайте эти файлы, там больше строк, для большей наглядности. На этих примерах будет видна не корректная работа. находит почему то всегда 3 похожих строки (хотя похожих там очень много, но всегда указывает только на 3)
http://autoit-script.ru/index.php?topic=21952.0 1.txt
http://autoit-script.ru/index.php?action=dlattach;topic=21952.0;attach=1631 2.txt


Я после ConslWrite добавил для наглядности ''MsgBox(1,'',($aArray1[$i])[3] & ' ' & ($aArray2[$i])[3])'' - показывает одинаковые числа.
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
Файл 1.txt мне предлагает скачать с первого поста...
Всегда указывает одни и те же места-строки
Скрипт после запуска останавливать не нужно, по идее - он всё время проверяет номер последней строки в файле 1.txt и если он изменился в большую сторону (дописались строки) то идёт сравнение только новых строк, если в меньшую (заполнился файл 1.txt и началась запись заново) - то проверяет заново с 1-й строки.
И ещё вопрос : поиск строки с ценой нужен именно в два раза меньшей или есть диапазон плюс-минус ?
 
Автор
D

Dk

Новичок
Сообщения
358
Репутация
2
Re:

ra4o сказал(а):
Файл 1.txt мне предлагает скачать с первого поста...
Всегда указывает одни и те же места-строки
Скрипт после запуска останавливать не нужно, по идее - он всё время проверяет номер последней строки в файле 1.txt и если он изменился в большую сторону (дописались строки) то идёт сравнение только новых строк, если в меньшую (заполнился файл 1.txt и началась запись заново) - то проверяет заново с 1-й строки.
И ещё вопрос : поиск строки с ценой нужен именно в два раза меньшей или есть диапазон плюс-минус ?



1) Файл 1.txt с поста номер 10. Я его давал другому участнику.
Вы можете так же просто сами из файла 2 сделать файлы один, и изменить самому некоторые цифры для проверки.
2) В Два раза меньше - это просто для примера, в дальнейшем я буду менять на другие параметры. Единственное, что бы было округление до десятичных, но я не думаю, что это важно.
 
A

Alofa

Гость
Мой вариант (на проверку):
Код:
#include <Array.au3>
#include <WindowsConstants.au3>
#include <ListViewConstants.au3>
#include <GUIConstantsEx.au3>

Opt('GUIOnEventMode', 1)
Opt('TrayOnEventMode', 1)
Opt('TrayMenuMode', 3)

Local $asText1, $asText2, $sFile2GTime, $iOffset, $sFile1 = @ScriptDir & '\1.txt', $sFile2 = @ScriptDir & '\2.txt'
Local $hGUI, $ListView, $hButt1, $hButt2, $hGUIState, $hExit

_OpenFile2()

$hGUI = GUICreate('Список:', 600, 175, -1, -1)
GUISetBkColor(0xB9D1EA)
$ListView = GUICtrlCreateListView('ASIN-10   |Price[New]|Price[Old]|SalesRank|Name|Date & Time', 5, 5, 590, 125, -1, BitOR($LVS_EX_GRIDLINES, $LVS_EX_HEADERDRAGDROP))
$hButt1 = GUICtrlCreateButton('Очистить список', 100, 140, 150, 25)
$hButt2 = GUICtrlCreateButton('Выйти из программы', 350, 140, 150, 25)
$hGUIState = TrayCreateItem('Отобразить/Скрыть Окно')
TrayCreateItem('')
$hExit = TrayCreateItem('Выход')
GUISetOnEvent($GUI_EVENT_CLOSE, '_CLOSEClicked')
GUICtrlSetOnEvent($hButt1, '_ListViewClear')
GUICtrlSetOnEvent($hButt2, '_Exit')
TrayItemSetOnEvent($hGUIState, '_CLOSEClicked')
TrayItemSetOnEvent($hExit, '_Exit')
GUISetState(@SW_HIDE)

While 1
	If FileGetTime($sFile2, 0, 1) <> $sFile2GTime Then _OpenFile2()
	_FileExists($sFile1)
	$asText1 = FileRead($sFile1)
	If @error Then Exit MsgBox(16, 'Ошибка!', 'Неудалось открыть файл "1.txt".')
	$iExtended = @extended
	$asText1 = StringRegExpReplace($asText1, '(?i)N/A', '-1')
	$asText1 = StringRegExp($asText1, '\n"(\w{10,12})"\t(?:[^\t]+\t){2}([\d\,\-]+)\t(?:[^\t]+\t){5}([\d\,\-]+)', 3, $iOffset)

	For $i = 0 To UBound($asText1) - 3 Step 3
		$iIndex = _ArraySearch($asText2, $asText1[$i], 0, 0, 0, 1)
		If @error Then ContinueLoop
		$asText2[$iIndex] = StringRegExpReplace($asText2[$iIndex], '(?i)N/A', '-1')
		$asText2Split = StringSplit($asText2[$iIndex], '|')
		If @error Then ExitLoop
		If StringRegExpReplace($asText2Split[2], ',', '.') / StringRegExpReplace($asText1[$i + 1], ',', '.') >= 2 And StringRegExpReplace($asText1[$i + 2], ',', '.') < 300000 Then
			GUICtrlCreateListViewItem($asText1[$i] & '|' & $asText1[$i + 1] & '|' & $asText2Split[2] & '|' & _
			$asText1[$i + 2] & '|' & $asText2Split[3] & '|' & @MDAY & '/' & @MON & '/' & @YEAR & ' ' & @HOUR & ':' & @MIN, $ListView)
			GUISetState(@SW_SHOWNORMAL)
			SoundPlay(@WindowsDir & '\media\Windows Ringin.wav')
			_ArrayDelete($asText2, $iIndex)
		EndIf
	Next
	
	$iOffset = ($iExtended >= 3) ? $iExtended - 2 : 1
	Sleep(250)
WEnd

;======================================================================================================================
Func _OpenFile2()
	Dim $asText2
	$iOffset = 1
	_FileExists($sFile2)
	$asText2 = FileRead($sFile2)
	If @error Then Exit MsgBox(16, 'Ошибка!', 'Неудалось открыть файл "2.txt".')
	FileWrite($sFile2, @CRLF & '>>>> Data is read. Time: ' & @MDAY & '/' & @MON & '/' & @YEAR & ' ' & @HOUR & ':' & @MIN & ' <<<<')
	$sFile2GTime = FileGetTime($sFile2, 0, 1)
	$asText2 = StringRegExpReplace($asText2, '\n"(\w{10,12})"\t"([^\t]+)"\t[^\t]+\t([\d\,N/A]+).+', '${1}|${3}|${2}|')
	$asText2 = StringRegExp($asText2, '\v(.+)\|', 3)
	If @error Then Exit MsgBox(16, 'Ошибка!', 'Не удалось корректно прочитать "2.txt".')
EndFunc   ;==>_OpenFile2

Func _FileExists($sFile)
	$hTimer = TimerInit()
	Do
		If TimerDiff($hTimer) >= 2000 Then ExitLoop
		Sleep(100)
	Until FileExists($sFile)
EndFunc   ;==>_FileExists

Func _CLOSEClicked()
	GUISetState(BitAND(WinGetState($hGUI), 2) ? @SW_HIDE : @SW_SHOWNORMAL)
EndFunc   ;==>_CLOSEClicked

Func _ListViewClear()
	GUICtrlSendMsg($ListView, $LVM_DELETEALLITEMS, 0, 0)
EndFunc   ;==>_ListViewClear

Func _Exit()
	Exit
EndFunc   ;==>_Exit
Скрипт создает изначально скрытое окно, при срабатывании условия оно активируется (со звуком). При нажатии в окне на кнопку "Закрыть" окно скрывается в трей - программа продолжает работать. Иконка программы в системном трее имеет свое меню.
 
Автор
D

Dk

Новичок
Сообщения
358
Репутация
2
Re: Сравнение строк в столбцах в текстовом файле с разделителем - табуляция

Alofa сказал(а):
Мой вариант (на проверку):
Код:
#include <Array.au3>
#include <WindowsConstants.au3>
#include <ListViewConstants.au3>
#include <GUIConstantsEx.au3>

Opt('GUIOnEventMode', 1)
Opt('TrayOnEventMode', 1)
Opt('TrayMenuMode', 3)

Local $asText1, $asText2, $sFile2GTime, $iOffset, $sFile1 = @ScriptDir & '\1.txt', $sFile2 = @ScriptDir & '\2.txt'
Local $hGUI, $ListView, $hButt1, $hButt2, $hGUIState, $hExit

_OpenFile2()

$hGUI = GUICreate('Список:', 600, 175, -1, -1)
GUISetBkColor(0xB9D1EA)
$ListView = GUICtrlCreateListView('ASIN-10   |Price[New]|Price[Old]|SalesRank|Name|Date & Time', 5, 5, 590, 125, -1, BitOR($LVS_EX_GRIDLINES, $LVS_EX_HEADERDRAGDROP))
$hButt1 = GUICtrlCreateButton('Очистить список', 100, 140, 150, 25)
$hButt2 = GUICtrlCreateButton('Выйти из программы', 350, 140, 150, 25)
$hGUIState = TrayCreateItem('Отобразить/Скрыть Окно')
TrayCreateItem('')
$hExit = TrayCreateItem('Выход')
GUISetOnEvent($GUI_EVENT_CLOSE, '_CLOSEClicked')
GUICtrlSetOnEvent($hButt1, '_ListViewClear')
GUICtrlSetOnEvent($hButt2, '_Exit')
TrayItemSetOnEvent($hGUIState, '_CLOSEClicked')
TrayItemSetOnEvent($hExit, '_Exit')
GUISetState(@SW_HIDE)

While 1
	If FileGetTime($sFile2, 0, 1) <> $sFile2GTime Then _OpenFile2()
	_FileExists($sFile1)
	$asText1 = FileRead($sFile1)
	If @error Then Exit MsgBox(16, 'Ошибка!', 'Неудалось открыть файл "1.txt".')
	$iExtended = @extended
	$asText1 = StringRegExpReplace($asText1, '(?i)N/A', '-1')
	$asText1 = StringRegExp($asText1, '\n"(\w{10,12})"\t(?:[^\t]+\t){2}([\d\,\-]+)\t(?:[^\t]+\t){5}([\d\,\-]+)', 3, $iOffset)

	For $i = 0 To UBound($asText1) - 3 Step 3
		$iIndex = _ArraySearch($asText2, $asText1[$i], 0, 0, 0, 1)
		If @error Then ContinueLoop
		$asText2[$iIndex] = StringRegExpReplace($asText2[$iIndex], '(?i)N/A', '-1')
		$asText2Split = StringSplit($asText2[$iIndex], '|')
		If @error Then ExitLoop
		If StringRegExpReplace($asText2Split[2], ',', '.') / StringRegExpReplace($asText1[$i + 1], ',', '.') >= 2 And StringRegExpReplace($asText1[$i + 2], ',', '.') < 300000 Then
			GUICtrlCreateListViewItem($asText1[$i] & '|' & $asText1[$i + 1] & '|' & $asText2Split[2] & '|' & _
			$asText1[$i + 2] & '|' & $asText2Split[3] & '|' & @MDAY & '/' & @MON & '/' & @YEAR & ' ' & @HOUR & ':' & @MIN, $ListView)
			GUISetState(@SW_SHOWNORMAL)
			SoundPlay(@WindowsDir & '\media\Windows Ringin.wav')
			_ArrayDelete($asText2, $iIndex)
		EndIf
	Next
	
	$iOffset = ($iExtended >= 3) ? $iExtended - 2 : 1
	Sleep(250)
WEnd

;======================================================================================================================
Func _OpenFile2()
	Dim $asText2
	$iOffset = 1
	_FileExists($sFile2)
	$asText2 = FileRead($sFile2)
	If @error Then Exit MsgBox(16, 'Ошибка!', 'Неудалось открыть файл "2.txt".')
	FileWrite($sFile2, @CRLF & '>>>> Data is read. Time: ' & @MDAY & '/' & @MON & '/' & @YEAR & ' ' & @HOUR & ':' & @MIN & ' <<<<')
	$sFile2GTime = FileGetTime($sFile2, 0, 1)
	$asText2 = StringRegExpReplace($asText2, '\n"(\w{10,12})"\t"([^\t]+)"\t[^\t]+\t([\d\,N/A]+).+', '${1}|${3}|${2}|')
	$asText2 = StringRegExp($asText2, '\v(.+)\|', 3)
	If @error Then Exit MsgBox(16, 'Ошибка!', 'Не удалось корректно прочитать "2.txt".')
EndFunc   ;==>_OpenFile2

Func _FileExists($sFile)
	$hTimer = TimerInit()
	Do
		If TimerDiff($hTimer) >= 2000 Then ExitLoop
		Sleep(100)
	Until FileExists($sFile)
EndFunc   ;==>_FileExists

Func _CLOSEClicked()
	GUISetState(BitAND(WinGetState($hGUI), 2) ? @SW_HIDE : @SW_SHOWNORMAL)
EndFunc   ;==>_CLOSEClicked

Func _ListViewClear()
	GUICtrlSendMsg($ListView, $LVM_DELETEALLITEMS, 0, 0)
EndFunc   ;==>_ListViewClear

Func _Exit()
	Exit
EndFunc   ;==>_Exit
Скрипт создает изначально скрытое окно, при срабатывании условия оно активируется (со звуком). При нажатии в окне на кнопку "Закрыть" окно скрывается в трей - программа продолжает работать. Иконка программы в системном трее имеет свое меню.


Вот это сильная тема, прям полноценная программа)
Сейчас у нас уже поздно, а для полного теста мне надо часа 2. завтра ОБЯЗАТЕЛЬНО проверю.
Один вопрос сразу. Если выскочило окошко, а я не нажал закрыть, программа будет работать дальше?
 
A

Alofa

Гость
Re: Сравнение строк в столбцах в текстовом файле с разделителем - табуляция

Dk сказал(а):
Один вопрос сразу. Если выскочило окошко, а я не нажал закрыть, программа будет работать дальше?
Процесс программы кружиться в бесконечном цикле до тех пор, пока вы не нажали в окне кнопку "Выйти из программы" или в трее "Выход" (ну или ошибка какая :scratch:).
 
Автор
D

Dk

Новичок
Сообщения
358
Репутация
2
Re: Сравнение строк в столбцах в текстовом файле с разделителем - табуляция

Alofa сказал(а):
Dk сказал(а):
Один вопрос сразу. Если выскочило окошко, а я не нажал закрыть, программа будет работать дальше?
Процесс программы кружиться в бесконечном цикле до тех пор, пока вы не нажали в окне кнопку "Выйти из программы" или в трее "Выход" (ну или ошибка какая :scratch:).

Уже тестирую, программа вообще бомба космическая! Пока полёт нормальный. :laugh: :-[ :-[
 
A

Alofa

Гость
Да, забыл сказать:
При каждом открытии файла "2.txt" скрипт дописывает в него строку примерно следующего содержания
[box]>>>> Data is read. Time: 16/03/2016 23:57 <<<<[/box]
За это отвечает строка:
Код:
FileWrite($sFile2, @CRLF & '>>>> Data is read. Time: ' & @MDAY & '/' & @MON & '/' & @YEAR & ' ' & @HOUR & ':' & @MIN & ' <<<<')

Можете закомментировать или удалить, если не нравится.

За воспроизведение звука отвечает:
Код:
SoundPlay(@WindowsDir & '\media\Windows Ringin.wav')
 
Автор
D

Dk

Новичок
Сообщения
358
Репутация
2
Re:Сравнение строк в столбцах в текстовом файле с разделителем - табуляция

Alofa сказал(а):
Да, забыл сказать:
При каждом открытии файла "2.txt" скрипт дописывает в него строку примерно следующего содержания
[box]>>>> Data is read. Time: 16/03/2016 23:57 <<<<[/box]
За это отвечает строка:
Код:
FileWrite($sFile2, @CRLF & '>>>> Data is read. Time: ' & @MDAY & '/' & @MON & '/' & @YEAR & ' ' & @HOUR & ':' & @MIN & ' <<<<')

Можете закомментировать или удалить, если не нравится.

За воспроизведение звука отвечает:
Код:
SoundPlay(@WindowsDir & '\media\Windows Ringin.wav')


Здравствуйте,
программа работает идеально!

В ходе проверки, я увидел 2 вещи, которые мне были бы нужны.

1) Я не могу скопировать с окошка оповещения текст. Есть ли возможность это сделать? (Можно в принципе и запись в файл сделать и копировать от туда, но это не совсем удобно)
2) И сделать ISBN номер как URL, что бы по клику в окошке оповещения открывался browser с адресом (просто номер)
3) Ну и в идеале хотелось бы, что бы шла отправка на E-mail(но я понимаю, это уже дело не 5 минут, наверно)

Разумеется если есть у Вас время и желание.
А так всё супер, спасибо огромное!

PS

Можно ещё уточнить, программа сравнивает только новые строки в файле 1.тхт Или всегда сравнивает заново от начало до конца.
Например 100 строк сравнила, потом была запись, стало 101 строка, программа будет сравнивать снова от 1 до 101 или только строку 101, пока файл 1.тхт не обновится?
Просто входе проверки, программа примерно в 80% показывает на 7-10 минут позже совпадение. Например новая строка в файле 1.тхт (она находится к примеру ближе к концу файла) была записана в 10:00, а оповещение приходит примерно в 10:07. Я не могу понять откуда задержка
Я понимаю я это не прописывал в условиях программы. Это условие выяснилось уже в ходе работы - обсуждения, но мне нужно, что бы программа читала только всегда новую строку. Мне очень важны эти 7 Минут. Пожалуй это самое важное, что хотелось бы изменить.
 
A

Alofa

Гость
Re:Сравнение строк в столбцах в текстовом файле с разделителем - табуляция

Dk сказал(а):
... программа сравнивает только новые строки в файле 1.тхт
Да.

Dk сказал(а):
... программа примерно в 80% показывает на 7-10 минут позже совпадение.
Не знаю, у меня так на это меньше секунды тратится (Autoit v3.3.12.0, запуск от имени Администратора). Но у меня и нет программы которая постоянно изменяет "1.txt", эмитировал ее работу через блокнот. Попробуйте также для сравнения.
Для проформы попробуйте работу скрипта без:
Код:
SoundPlay(@WindowsDir & '\media\Windows Ringin.wav')
... и отпишитесь.

Все остальное - позже.
 
Автор
D

Dk

Новичок
Сообщения
358
Репутация
2
Re:Сравнение строк в столбцах в текстовом файле с разделителем - табуляция

Dk сказал(а):
... программа примерно в 80% показывает на 7-10 минут позже совпадение.
Не знаю, у меня так на это меньше секунды тратится (Autoit v3.3.12.0, запуск от имени Администратора). Но у меня и нет программы которая постоянно изменяет "1.txt", эмитировал ее работу через блокнот. Попробуйте также для сравнения.
Для проформы попробуйте работу скрипта без:
Код:
SoundPlay(@WindowsDir & '\media\Windows Ringin.wav')
... и отпишитесь.
Все остальное - позже.

Через NotePad срабатывает мгновенно.
А при работе с файлами другой программы эффект тот же. Звуковое оповещение отключил. Смысл такой, программа (которая обновляет файлы) скидывает мне на e-mail быстрее, чем скрипт показывает совпадения условий. Недостаток той чужой программы, в том что она ждёт когда файл 1.тхт полностью обновится (дойдёт до конца) и только потом скидывает все совпадения. Иногда скрипт показывает раньше совпадения, но 80% позже (от 2 до 7-ми минут) И причём закономерность такая, чем строка ближе к концу файла находится, тем больше опоздание. Ну ок. Оставим пока это. Я ещё понаблюдаю.
Буду очень рад если вы сделаете другие пункты, когда будет у Вас время.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Код:
Func _FileExists($sFile) 
	Local $iTimer = TimerInit()
	Do
		Sleep(250)
	Until FileExists($sFile) Or TimerDiff($iTimer) >= 2000
EndFunc

StringRegExpReplace($asText1, '(?i)N/A', '-1') => StringReplace($asText1, 'N/A', -1)
StringRegExpReplace($asText1[$i + 1], ',', '.') => StringReplace($asText1[$i + 1], ',', '.')
:smile:
 
A

Alofa

Гость
inververs спасибо за подсказки, правда спасибо.
Они навели меня на один существенный Тормоз в коде, вот здесь:
Код:
$asText1 = StringRegExpReplace($asText1, '(?i)N/A', '-1')
 $asText1 = StringRegExp($asText1, '\n"(\w{10,12})"\t(?:[^\t]+\t){2}([\d\,\-]+)\t(?:[^\t]+\t){5}([\d\,\-]+)', 3, $iOffset)

К сожалению сейчас нет доступа к компьютеру - тестировать не могу.
Dk исправлю вечером.
 
Автор
D

Dk

Новичок
Сообщения
358
Репутация
2
Re:Сравнение строк в столбцах в текстовом файле с разделителем - табуляция

К сожалению сейчас нет доступа к компьютеру - тестировать не могу.
Dk исправлю вечером.


Будем ждать :-[
 
A

Alofa

Гость
Dk протестируйте ка на скорость пока это:
Код:
#include <Array.au3>
#include <WindowsConstants.au3>
#include <ListViewConstants.au3>
#include <GUIConstantsEx.au3>

Opt('GUIOnEventMode', 1)
Opt('TrayOnEventMode', 1)
Opt('TrayMenuMode', 3)

Local $vVar, $asText1, $asText2, $sFile2GTime, $iOffset, $sFile1 = @ScriptDir & '\1.txt', $sFile2 = @ScriptDir & '\2.txt'
Local $hGUI, $ListView, $hButt1, $hButt2, $hGUIState, $hExit

_OpenFile2()

$hGUI = GUICreate('Список:', 600, 175, -1, -1)
GUISetBkColor(0xB9D1EA)
$ListView = GUICtrlCreateListView('ASIN-10   |Price[New]|Price[Old]|SalesRank|Name|Date & Time', 5, 5, 590, 125, -1, BitOR($LVS_EX_FULLROWSELECT,$LVS_EX_GRIDLINES, $LVS_EX_HEADERDRAGDROP))
$hButt1 = GUICtrlCreateButton('Очистить список', 100, 140, 150, 25)
$hButt2 = GUICtrlCreateButton('Выйти из программы', 350, 140, 150, 25)
$hGUIState = TrayCreateItem('Отобразить/Скрыть Окно')
TrayCreateItem('')
$hExit = TrayCreateItem('Выход')
GUISetOnEvent($GUI_EVENT_CLOSE, '_CLOSEClicked')
GUICtrlSetOnEvent($hButt1, '_ListViewClear')
GUICtrlSetOnEvent($hButt2, '_Exit')
TrayItemSetOnEvent($hGUIState, '_CLOSEClicked')
TrayItemSetOnEvent($hExit, '_Exit')
GUISetState(@SW_HIDE)

While 1
	If FileGetTime($sFile2, 0, 1) <> $sFile2GTime Then _OpenFile2()
	$asText1 = _FileRead($sFile1)
	If @error Then Exit MsgBox(16, 'Ошибка!', 'Неудалось открыть файл "1.txt".')
	$iExtended = @extended
	$asText1 = StringRegExp($asText1, '\n"(\w{10,12})"\t(?:[^\t]+\t){2}([\d\,N/A]+)\t(?:[^\t]+\t){5}([\d\,N/A]+)', 3, $iOffset)
	
	For $i = 0 To UBound($asText1) - 3 Step 3
		$iIndex = _ArraySearch($asText2, $asText1[$i], 0, 0, 0, 1)
		If @error Then ContinueLoop
		$asText2Split = StringSplit($asText2[$iIndex], '|')
		If @error Then ExitLoop
		$vVar = ($asText1[$i + 2] = 'N/A') ? -1 : $asText1[$i + 2]
		If $asText2Split[2] <> 'N/A' Or $asText1[$i + 1] <> 'N/A' Then
			If StringReplace($asText2Split[2], ',', '.') / StringReplace($asText1[$i + 1], ',', '.') >= 2 And StringReplace($vVar, ',', '.') < 300000 Then
				GUICtrlCreateListViewItem($asText1[$i] & '|' & $asText1[$i + 1] & '|' & $asText2Split[2] & '|' & _
						$asText1[$i + 2] & '|' & $asText2Split[3] & '|' & @MDAY & '/' & @MON & '/' & @YEAR & ' ' & @HOUR & ':' & @MIN, $ListView)
				GUISetState(@SW_SHOWNORMAL)
				SoundPlay(@WindowsDir & '\media\Windows Ringin.wav')
			EndIf
		EndIf
		_ArrayDelete($asText2, $iIndex)
	Next
	
	$iOffset = ($iExtended >= 3) ? $iExtended - 2 : 1
	Sleep(250)
WEnd

;======================================================================================================================
Func _OpenFile2()
	Dim $asText2
	$iOffset = 1
	$asText2 = _FileRead($sFile2)
	If @error Then Exit MsgBox(16, 'Ошибка!', 'Неудалось открыть файл "2.txt".')
	FileWrite($sFile2, @CRLF & '>>>> Data is read. Time: ' & @MDAY & '/' & @MON & '/' & @YEAR & ' ' & @HOUR & ':' & @MIN & ' <<<<')
	$sFile2GTime = FileGetTime($sFile2, 0, 1)
	$asText2 = StringRegExpReplace($asText2, '\n"(\w{10,12})"\t"([^\t]+)"\t[^\t]+\t([\d\,N/A]+).+', '${1}|${3}|${2}|')
	$asText2 = StringRegExp($asText2, '\v(.+)\|', 3)
	If @error Then Exit MsgBox(16, 'Ошибка!', 'Не удалось корректно прочитать "2.txt".')
EndFunc   ;==>_OpenFile2

Func _FileRead($sFile)
	For $i = 0 To 20
		$sChars = FileRead($sFile)
		If $sChars Then Return $sChars
		Sleep(90)
	Next
	Return SetError(1)
EndFunc   ;==>_FileRead

Func _CLOSEClicked()
	GUISetState(BitAND(WinGetState($hGUI), 2) ? @SW_HIDE : @SW_SHOWNORMAL)
EndFunc   ;==>_CLOSEClicked

Func _ListViewClear()
	GUICtrlSendMsg($ListView, $LVM_DELETEALLITEMS, 0, 0)
EndFunc   ;==>_ListViewClear

Func _Exit()
	Exit
EndFunc   ;==>_Exit
Не вижу смысла заниматься остальными доработками, пока не устраним главный затык.
 
Верх