Приложение 1. Пример скрипта на языке Lua

В данном приложении приведен пример скрипта на языке Lua для создания таблицы в Рабочем месте QUIK.

Файл table_object.lua:

dofile (getScriptPath() .. "\\quik_table_wrapper.lua")
dofile (getScriptPath() .. "\\ntime.lua")
stopped = false
function format1(data)
	return string.format("0x%08X", data)
end

function format2(data)
	return string.format("%06d", data)
end

function OnStop(s)
	stopped = true
end

function main()
	-- поворачивающиеся «палочки» в заголовке таблицы
	local palochki = {"-","\\", "|", "/"}
	-- создать экземпляр QTable
	t = QTable.new()
	if not t then
		message("error!", 3)
		return
	else
		message("table with id = " ..t.t_id .. " created", 1)
	end

	-- добавить два столбца с функциями форматирования
	-- в первом столбце – hex-значения, во втором – целые числа
	t:AddColumn("test1", QTABLE_INT_TYPE, 10,format1)
	t:AddColumn("test2", QTABLE_INT_TYPE, 10, format2)
	-- добавить столбцы без форматирования
	t:AddColumn("test3", QTABLE_CACHED_STRING_TYPE, 50)
	t:AddColumn("test4", QTABLE_TIME_TYPE, 50)
	t:AddColumn("test5", QTABLE_CACHED_STRING_TYPE, 50)
	
	t:SetCaption("Test")
	t:Show()
	i=1
	-- исполнять цикл, пока пользователь не остановит скрипт из диалога управления
	while not stopped do 
		-- если таблица закрыта, то показать ее заново
		-- при этом все предыдущие данные очищаются
		if t:IsClosed() then
			t:Show()
		end
		-- на каждой итерации повернуть «палочку» на 45 градусов
		t:SetCaption("QLUA TABLE TEST " .. palochki[i%4 +1])
		-- метод добавит в таблицу новую строчку и вернет ее номер
		local row = t:AddLine()
		t:SetValue(row, "test1", row, i)
		t:SetValue(row, "test2", row, i)

		-- заполнить ячейку текущим заголовком таблицы
		-- тип столбца – строковый, поэтому последний параметр пропускается
		SetCell(t.t_id, row, 3, GetWindowCaption(t.t_id))
		
		_date = os.date("*t")
		-- 4-й столбец заполнить данными типа время (число в формате <ЧЧММСС>)
		-- Функция для строкового представления времени определена в файле ntime.lua
		-- Функция NiceTime возвращает строку
		SetCell(t.t_id, row, 4, 
		NiceTime(_date) .. string.format(" (%02d:%02d:%02d)", _date.hour, _date.min, _date.sec),
		_date.hour*10000+_date.min*100 +_date.sec)
		-- пятый столбец имеет строковый тип и заполняется результатом выполнения функции NiceTime
		-- исходный код функции взят из виджета Conky Lua для Ubuntu
		SetCell(t.t_id, row, 5, NiceTime(_date))
		sleep(1000)
		i=i+1
	end
	message("finished")
end

Файл quik_table_wrapper.lua:

-- Перегрузка функции message с необязательным вторым параметром
old_message = message
function message(v, i)
	old_message(tostring(v), i or 1)
end


QTable ={}
QTable.__index = QTable

-- Создать и инициализировать экземпляр таблицы QTable
function QTable.new()
	local t_id = AllocTable()
	if t_id ~= nil then
		q_table = {}
		setmetatable(q_table, QTable)
		q_table.t_id=t_id
		q_table.caption = ""
		q_table.created = false
		q_table.curr_col=0
		-- таблица с описанием параметров столбцов
		q_table.columns={}
		return q_table
	else
		return nil
	end
end

function QTable:Show()
	-- отобразить в терминале окно с созданной таблицей
	CreateWindow(self.t_id)
	if self.caption ~="" then
		-- задать заголовок для окна
		SetWindowCaption(self.t_id, self.caption)
	end
	self.created = true
end
function QTable:IsClosed()
	-- если окно с таблицей закрыто, возвращает «true»
	return IsWindowClosed(self.t_id)
end

function QTable:delete()
	-- удалить таблицу
	DestroyTable(self.t_id)
end

function QTable:GetCaption()
	if IsWindowClosed(self.t_id) then
		return self.caption
	else
		-- возвращает строку, содержащую заголовок таблицы
		return GetWindowCaption(self.t_id)
	end
end

-- Задать заголовок таблицы
function QTable:SetCaption(s)
	self.caption = s
	if not IsWindowClosed(self.t_id) then
		res = SetWindowCaption(self.t_id, tostring(s))
	end
end

-- Добавить описание столбца <name> типа <c_type> в таблицу
-- <ff> – функция форматирования данных для отображения
function QTable:AddColumn(name, c_type, width, ff )
	local col_desc={}
	self.curr_col=self.curr_col+1
	col_desc.c_type = c_type
	col_desc.format_function = ff
	col_desc.id = self.curr_col
	self.columns[name] = col_desc
	-- <name> используется в качестве заголовка таблицы
	AddColumn(self.t_id, self.curr_col, name, true, c_type, width)
end

function QTable:Clear()
	-- очистить таблицу
	Clear(self.t_id)
end

-- Установить значение в ячейке
function QTable:SetValue(row, col_name, data)
	local col_ind = self.columns[col_name].id or nil
	if col_ind == nil then
		return false
	end
	-- если для столбца задана функция форматирования, то она используется
	local ff = self.columns[col_name].format_function
	
	if type(ff) == "function" then
		-- в качестве строкового представления используется
		-- результат выполнения функции форматирования
		SetCell(self.t_id, row, col_ind, ff(data), data)
		return true
	else
		SetCell(self.t_id, row, col_ind, tostring(data), data)
	end
end

function QTable:AddLine()
	-- добавляет в конец таблицы пустую строчку и возвращает ее номер
	return InsertRow(self.t_id, -1)
end

function QTable:GetSize()
	-- возвращает размер таблицы
	return GetTableSize(self.t_id)
end

-- Получить данные из ячейки по номеру строки и имени столбца
function QTable:GetValue(row, name)
	local t={}
	local col_ind = self.columns[name].id
	if col_ind == nil then
		return nil
	end
	t = GetCell(self.t_id, row, col_ind)
	return t
end

-- Задать координаты окна
function QTable:SetPosition(x, y, dx, dy)
	return SetWindowPos(self.t_id, x, y, dx, dy)
end

-- Функция возвращает координаты окна
function QTable:GetPosition()
	top, left, bottom, right = GetWindowRect(self.t_id)
	return top, left, right-left, bottom-top
end

Файл ntime.lua:

words = {"one ", "two ", "three ", "four ", "five ", "six ", "seven ", "eight ", "nine "}
levels = {"thousand ", "million ", "billion ", "trillion ", "quadrillion ", "quintillion ", "sextillion ", "septillion ", "octillion ", [0] = ""}
iwords = {"ten ", "twenty ", "thirty ", "forty ", "fifty ", "sixty ", "seventy ", "eighty ", "ninety "}
twords = {"eleven ", "twelve ", "thirteen ", "fourteen ", "fifteen ", "sixteen ", "seventeen ", "eighteen ", "nineteen "}

function digits(n)
	local i, ret = -1
	return function()
	i, ret = i + 1, n % 10
	if n > 0 then
	n = math.floor(n / 10)
	return i, ret
	end
	end
end

level = false
function getname(pos, dig)
	level = level or pos % 3 == 0
	if(dig == 0) then return "" end
	local name = (pos % 3 == 1 and iwords[dig] or words[dig]) .. (pos % 3 == 2 and "hundred " or "")
	if(level) then name, level = name .. levels[math.floor(pos / 3)], false end
	return name
end

function numberToWord(number)
	if(number == 0) then return "zero" end
	vword = ""
	for i, v in digits(number) do
	vword = getname(i, v) .. vword
	end

	for i, v in ipairs(words) do
	vword = vword:gsub("ty " .. v, "ty-" .. v)
	vword = vword:gsub("ten " .. v, twords[i])
	end
	return vword
end

function _Time(t)
	hour = t.hour
	minute = t.min
	hour = hour % 12
	if(hour == 0) then 
	hour, nextHourWord = 12, "one "
	else
	nextHourWord = numberToWord(hour+1)
	end
	hourWord = numberToWord(hour)
	if(minute == 0 ) then 
	return hourWord .. "o'clock"
	elseif(minute == 30) then
	return "half past " .. hourWord
	elseif(minute == 15) then
	return "a quarter past " .. hourWord 
	elseif(minute == 45) then
	return "a quarter to " .. nextHourWord 
	else
	if(minute < 30) then
	return numberToWord(minute) .. "past " .. hourWord
	else
	return numberToWord(60-minute) .. "to " .. nextHourWord
	end
	end
end

function _Seconds(s)
	return numberToWord(s)
end

function NiceTime(t)
	return _Time(t) .."and ".. _Seconds(t.sec) .. "second"
end

В результате выполнения скрипта в Рабочем месте QUIK создается таблица вида: