翻译:lovem
上个星期,告诉你了如何创建一个简单的数据库。这个星期,我们将扩展这个程序,使其包括保存和导入数据功能,这样你就不需要每次都从输入一通数据而开始这个程序。我也将告诉你,如何将数据库里的信息导出成一个格式,以使别的程序也能读取,就像微软的Excel。当程序运行时,数据都存储在全局变量gDatabase里,这是一个表,事实上是一个大表中的一个分表,这个大表中每一个分表都单独存储在数据库里。下面就是从“Message窗口”中看到的这个大表:
put gDatabase
-- [["Name": "Gary", "Street": "123 Clever Rd", "City": "Denver", "State": "CO", "Zip": "80210", "Phone": "720-555-1212", "Birthday": "2/29/69"], ["Name": "Natasha", "Street": "123 Clever Rd", "City": "Denver", "State": "CO", "Zip": "80210", "Phone": "303-555-5555", "Birthday": "5/1/99"]]
Director不能直接将这个表存到文件里,但是它可以将这个表转换为字符串再保存。转换为字符串只需简单的应用string函数。下面就是:
on saveData
-- convert list to a string
text = string(gDatabase)
-- send string to text file
saveText(text)
end
这个saveText函数是我用FileIO插件制作的一个标准函数,它能保存文本文件,这是从我的《使用Director 8》一书中第369页引用的,我也在以前的文章中介绍过。我不再将这些代码加到这里来,但你可以从那两个地方找到这些代码,也可以从这篇文章的源文件中找到。
一旦你保存了数据,你就可以从Mac中的SimpleText和Windows的记事本或写字板中打开,你可以看到表以字符串形式整齐地排列在里面。
将数据读回到程序里有点复杂。首先,你得考虑是否用户被问及文件名时会按“Cancel”按钮。同样,如果他们选择的文件有问题,你得告诉他们。
以下是loadData函数的语句。使用了value函数以试着将字符串转换成表。也使用了listP函数以检测表是否转换成功。
on loadData
-- get contents of text file
text = openAndReadText ()
-- if text file is empty, could mean the dialog was cancelled
if text = "" then exit
-- convert string to list
list = value (text)
-- did the conversion work?
if listP (list) then
-- yes, so set the database to this list
gDatabase = list
else
-- no, must be a bas file
alert "Error reading database."
end if
end
即使用户选择了正确的文件,value函数仍有可能出错。这就是Director的字符串可以包含quote(双引号)特性的缘故。所以,如果用户键入了他们的名字,如“John "JS" Smith”,接着程序将其保存但却没有包括全部双引号:其实,这个名字的前后双引号的中间部分都是名字的一部分。然而,当value函数试着解释这个名字时,它将会将所有的双引号一个个解释并转换为表。这就会产生错误,value函数停止运行而给表返回VOID值。
有一些办法可以避免这个错误。我最喜欢的一个方法是确保输入框不接受双引号,或者,可以接受双引号,但得转换成安全的单引号。另一种选择就是当第一次存储时,将记录的每一个项目的双引号转换为单引号。
saveDate和loadData函数提供了保存和导入数据库的功能。你甚至可以保存任何单独的不同的数据库。然而这些文件都不能被其他程序所读取。让我们创建一个可以将数据以Tab分隔符形式保存的输出功能,这样就可以让诸如微软的Excel等别的程序读取了。
这有一个窍门可以用TAB保存每一个项目。你也可以在每个记录之间加个RETURN。这个输出功能甚至会用表的属性来创建一行标题。所有这些都将变成文本串,当这个文本串完成后,它将被与saveText相同的函数保存。
on export
if gDatabase.count < 1 then
-- if no data yet, then show message instead
alert "No data."
else
-- create blank string
text = ""
-- add each of the column headings
repeat with i = 1 to gDatabase[1].count
put getPropAt (gDatabase[1],i) & TAB after text
end repeat
-- add each record
repeat with m = 1 to gDatabase.count
-- new line
put RETURN after text
-- add each field of each record
repeat with j = 1 to gDatabase[m].count
put gDatabase[m][j]&TAB after text
end repeat
end repeat
-- send string to text file
saveText (text)
end if
end
这时的文本文件可以用SimpleText和记事本等打开。呵呵,现在它比表形式的文本好读多了。