SeeCSV.tcl

Простой, по быстрому сделанный, но весьма полезный tcl скрипт для просмотра CSV файлов. Отображает в окне таблицу полученную из CSV в порядке «от новых к старым» (то есть более новые записи наверху). При дозаписи данных кем-то, дочитывает новые строки. В текущей версии разделителем полей считает ; а файлы читает как unicode (как их пишет MQL).

Запускать: SeeCSV.tcl файл_журнала.csv

SeeCSV.tcl
#/usr/bin/tclsh

# скроллируемая CSV таблица 
package require Tk

# фрейм скроллируемой таблицы
proc TableFrame { w } {
	frame $w
 
	ttk::treeview $w.table -show headings -yscrollcommand [ list $w.vscroll set ] -xscrollcommand [ list $w.hscroll set]
	scrollbar $w.vscroll -orient vert -command [ $w.table yview ]
	scrollbar $w.hscroll -orient hor -command [ $w.table xview ]
 
	grid $w.table -column 0 -row 0 -sticky "nsew"
	grid $w.vscroll -column 1 -row 0 -sticky "ns"
	grid $w.hscroll -column 0 -row 1 -sticky "ew" 
 
	grid columnconfigure $w 0 -weight 1
	grid rowconfigure $w 0 -weight 1
 
	return $w
}

# добавить строку(готовый список) к таблице
proc TableFrame_AddList { w ls } {
	# кол-во элементов в списке и колонок в таблице
	set items [ llength $ls ]
	set columns [ llength [ $w.table cget -columns ] ]
	if { $columns < $items } {
		# в таблице меньше колонок чем элементов в списке - надо добавить колонки
		$w.table configure -columns [ range 0 [ expr $items - 1 ] ]
		for { set n $columns } { $n < $items } { incr n } {
			$w.table heading $n -text $n
		}
	} elseif { $items < $columns } {
		# в списке меньше элементов чем колонок в таблице - надо дополнить список
		set ls [ linsert $ls end [ lrepeat [ expr $columns - $items ] "" ] ]
	}
	# вставить список в таблицу
	set row [ $w.table insert {} 0 -values $ls ]
	return $row
}
 
proc GUI { fileName } {
	wm title . "CSV [ file tail $fileName ]"
	set csv [ TableFrame .csv ]
	pack .csv -fill both -expand yes
}
# прочесть строку из файла, сделать из неё список и передать в таблицу
proc ReadString { f csv } {
	set row {}
	while { ! [ eof $f ] } {
		set ls {}
		set s [ gets $f ]
		if { $s == {} } break
		foreach item [ split $s ";" ] {
			lappend ls [ string trim $item ]
		}
		set row [ TableFrame_AddList $csv $ls ]
	}
	seek $f 0 end
	if { $row != {} } {
		$csv.table see $row
	}
}
proc CheckForNewData { f csv fileName } {
	set filePos [ tell $f ]
	set fileSize [ file size $fileName ]
	if { $filePos<$fileSize } {
		ReadString $f $csv
	}
	after 5000 [ list CheckForNewData $f .csv $fileName ]
}
proc range { from to } {
	set ls {}
	for {set t $from} { $t<=$to} { incr t } {
		lappend ls $t
	}
	return $ls
}
set fileName [ lindex $argv end ]
 
GUI $fileName
 
set f [ open $fileName "r" ]
fconfigure $f -encoding unicode -buffering line
fileevent $f readable [ ReadString $f .csv ]
# мелкая затыка для виндвз, в нём по нормальному неработает
after 5000 [ list CheckForNewData $f .csv $fileName ]
 
tkwait window .