فصل ۲۹ — پایش آمار جدولها
در Applicationهای بزرگ و پیچیدهٔ Access پیگیری آنچه واقعاً در Database رخ میدهد دشوار است. Tableها، بهویژه هنگام Import حجم زیاد داده از منابع خارجی، رشد میکنند و اندازهشان تغییر میکند. مشاهدهٔ تغییر اندازهٔ جدولها به Developer و بعضی Userها کمک میکند بفهمند Application درست کار میکند یا نه. اگر مثلاً تعداد رکوردهای مورد انتظار از یک منبع خارجی مشخص باشد، Table مقصد نیز باید دقیقاً به همان تعداد رشد کند.
این بررسیها گاهی «sanity» یا «health» check نامیده میشوند و برای Reconcile کردن Tableها، پیدا کردن دادهٔ اضافی یا ناپدیدشدن غیرمنتظرهٔ رکوردها مفیدند.
در Northwind جدولی برای Statistics بسازید با سه Field: TableName از نوع Text(255)، TableSize از نوع Number/Long Integer و TimeStamp از نوع Date/Time. Primary Key لازم نیست. نام Table را tblTableStatistics بگذارید.
Sub TableStatistics()
Dim RecSet As Recordset, RecSet1 As Recordset, TDef As TableDef
CurrentDb.Execute "delete * from tblTableStatistics" 'Optional
Set RecSet = CurrentDb.OpenRecordset("tblTableStatistics")
For Each TDef In CurrentDb.TableDefs
Set RecSet1 = CurrentDb.OpenRecordset(TDef.Name)
RecSet.AddNew
RecSet!TableName = TDef.Name
RecSet!TableSize = RecSet1.RecordCount
RecSet!TimeStamp = Now()
RecSet.Update
Next TDef
Set RecSet = Nothing
Set RecSet1 = Nothing
End Sub
کد دو Recordset و یک TableDef میسازد. Delete اولیه اختیاری است؛ اگر حذف شود میتوان History آماری را نگه داشت و بعداً با Range تاریخ/زمان وضعیت Database را در زمان مشخص پرسوجو کرد. Loop از تمام TableDefها میگذرد، Recordset دوم را برای شمارش رکوردها باز میکند و نام Table، تعداد رکوردها و Timestamp را در tblTableStatistics مینویسد.
ترکیب این روش با Audit Trail فصل ۲۵ ابزار مفیدی برای فهم دقیق وضعیت Application است. میتوان Procedure را با Timer فرم آغازین هر ساعت اجرا کرد و همچنین بلافاصله قبل و بعد از Import داده آن را فراخواند.
فصل ۳۰ — کار با فایلهای متنی بسیار بزرگ
در Access معمولاً فایلهای Text Import یا Link میشوند، بهویژه وقتی داده از Database خارجی میآید و مالک آن به دلایل Security یا Performance اجازهٔ اتصال مستقیم نمیدهد. مشکل زمانی است که Text File از ظرفیت عملی Access بزرگتر باشد. نویسنده نمونهای از فایل 4GB را شرح میدهد که Access حتی در Text File Wizard نیز قادر به مشاهدهٔ آن نبود و Notepad/WordPad هم برای بارگذاری بسیار کند بودند.
اول باید ساختار، Delimiterها و شکل داده مشخص شود. کد زیر ده سطر اول فایل بزرگ را در فایل نمونه مینویسد:
Sub CreateTenRows()
Dim temp As String
fnum = FreeFile
Open "C:\MyLargeFile.txt" For Input As fnum
fnum1 = FreeFile
Open "c:\FirstTenRows.txt" For Output As fnum1
For n = 1 To 10
Line Input #fnum, temp
Print #fnum1, temp
Next n
Close fnum
Close fnum1
End Sub
فایل 4GB برای Input باز میشود، فایل FirstTenRows برای Output ساخته میشود و Loop ده سطر را میخواند و مینویسد. نمونهٔ کوچک را میتوان بهسادگی بررسی کرد.
در مثال، Delimiterها Tilde (~) و Text Qualifierها Single Quote بودند. Access با Tilde خوب کار نمیکند و Qualifierها نیز برای Link ضروری نبودند. در فایل 4GB همین علامتها فضای قابلتوجهی میگیرند. کد زیر ~ را به Comma تبدیل و Single Quoteها را حذف میکند:
Sub GetMyBigFile()
Dim temp As String, temp1 As String
fnum = FreeFile
Open "C:\MyBigFile.txt" For Input As fnum
fnum1 = FreeFile
Open "c:\MySmallFile.txt" For Output As fnum1
Do While Not EOF(fnum)
Line Input #fnum, temp
temp1 = ""
For m = 1 To Len(temp)
If Mid(temp, m, 1) = "~" Then
temp1 = temp1 & ","
ElseIf Mid(temp, m, 1) = "'" Then
Else
temp1 = temp1 & Mid(temp, m, 1)
End If
Next m
Print #fnum1, temp1
Loop
Close fnum
Close fnum1
End Sub
هر سطر Character به Character پیمایش میشود؛ Tilde با Comma عوض، Single Quote نادیده گرفته و بقیهٔ کاراکترها به temp1 افزوده میشوند. اگر Apostrophe بخشی واقعی از متن باشد—مثل نام O’Leary—حذف آن مشکل ایجاد میکند.
اجرای Procedure در تجربهٔ نویسنده حدود 90 دقیقه طول کشید اما در پایان یک CSV بدون Text Qualifier بهدست آمد و Access توانست به آن Link شود. با این حال Query ساده روی فایل Linked هنوز مشکل داشت؛ راهحل تقسیم فایل به دو File و ساخت دو Linked File و سپس Union Query بود.
Sub CreateSplitFiles()
Dim temp As String, temp1 As String, temp2 As String, n As Long
n = 1
fnum = FreeFile
Open "C:\MyBigFile.txt" For Input As fnum
fnum1 = FreeFile
Open "c:\SmallFile1.txt" For Output As fnum1
fnum2 = FreeFile
Open "c:\SmallFile2.txt" For Output As fnum2
Do While Not EOF(fnum)
Line Input #fnum, temp
temp1 = ""
For m = 1 To Len(temp)
If Mid(temp, m, 1) = "~" Then
temp1 = temp1 & ","
ElseIf Mid(temp, m, 1) = "'" Then
Else
temp1 = temp1 & Mid(temp, m, 1)
End If
Next m
If n = 1 Then
Print #fnum2, temp1
End If
If n < 3500000 Then
Print #fnum1, temp1
Else
Print #fnum2, temp1
End If
n = n + 1
Loop
Close fnum
Close fnum1
Close Fnum2
End Sub
ردیف اول Header است و در هر دو Output لازم است؛ به همین دلیل وقتی n=1 است در فایل دوم هم نوشته میشود. تا 3,500,000 ردیف داده در SmallFile1 نوشته و پس از آن به SmallFile2 منتقل میشود. نقطهٔ تقسیم قراردادی است و برای هر File باید با آزمون انتخاب شود.
صفحهٔ پایانی این بخش در نسخهٔ اصلی عمداً خالی است.