تماما با اشراف نسبی بر داکیومنت سایت Office شامل آبجکتها و پراپرتی های مخصوص به کنترل باتن در اکسس و با راهنمایی متخصصین فروم های خارجی تهیه و در دسترس عموم گذاشته شد تا فراگیران با تسلط به مبانی گفته شده بتوانند ماژولی برای دستیابی بهتر از این اثر خلق نمایند .
یادرآوری میشود کنترل باتن و غیره در نمای دیزاین قابل ساخت است اگر کسی فایل را بصورت کامپایل شده ارائه دهد ( accde ) اگر ماژولی نوشته باشد که اتومات کنترلی را به فرم اضافه نماید بعلت اینکه در این حالت نمای دیزاین بسته میشه فقط خود را ضایع ساخته
جدول مربوطه :
فرم2 که فرم اصلیست و حاوی باتن های 0 تا 3 است و Stacked شده :
فرم 3 حاوی باتن های 0 تا 15 که به داخل فرم 2 کشیده شده و یکسری از پراپرتیهای آن فرم دستی تنطیم شده :
در وهله ی اول نوشتن تابعی و قرار دادن آن داخل رویداد کلیک هر یک از باتن های فرم 2
( Function SetSubButtons(c As Control
نوشتن لوپ برای صفر کردن پراپرتی BottomPadding باتن های فرم 2 اگر صفر نشوند معادلات شما بهم خواهد ریخت تست کنید
For i=0 to 3
Controls("Command" & i).BottomPadding = 0
Next
گرفتن آخرین مقدار Sub وارد شده در جدول طبق باتن فشرده شده در فرم 2
"'" & d = DLast("Sub", "Table1", "Main='" & c.Name
باز شدن فرم 3 که سابفرمیست در فرم 2 تا مقدار d که در بالا گرفته شد
Me.Form3.Height=Me.Form3.Controls("" & d & "").Top + Me.Form3.Controls("" & d & "").Height - 5
پراپرتی Left سابفرم 3 را معادل Left باتن فشرده شده در فرم 2 قرار میدهیم
Me.Form3.Left = c.Left
پراپرتی Top سابفرم 3 را تنظیم میکنیم تا سابفرم در زیر باتن فشرده شده در فرم 2 قرار گیرد
Me.Form3.Top = c.Top + c.Height + c.TopPadding
End Function
نکته :
در تابع باید قبل از لوپ نوشته شود که در صورتیکه BottomPadding کنترل فشرده شده مخالف صفر بود و همچنین ارتفاع سابفرم 3 مخالف صفر بود c.BottomPadding و Me.Form3.Height صفر شود در غیر اینصورت بعد از Next انجام شود
(Public Function SetSubButtonS(c As Control
If c.BottomPadding<>0 And Me.Form3.Height<>0 Then
c.BottomPadding=0: Me.form3.Height=0
Esle
For
.
.
Next
.
.
End if
End Fucntion
شکل زیر بیانگر تست شدن موارد بالاست البته چند مورد سلیقه ایست مثل باز شدن آبشاری زیر باتن های اصلی یا بسته شدن سابفرم 3 که با Pause انجام شده
برای باز شدن آبشاری باید از تابع Pause که در سایت ها گذاشته شده و از Timer ، حلقه و Doevents استفاده می کند بهره ببرید
برای اینکار نیازمند نوشتن لوپ دیگر در انتهای تابع بالا دارید بطوریکه یک سوم یک سوم به ارتفاع سابفرم 3 و همچنین پراپرتی BottomPadding کنترل فشرده شده اضافه شود ... برای کاهش زماینکه که سابفرم 3 باز است و روی همان کنترل کلیک می کنید می بایست در If بالا لوپی تعبیه گردد تا یک سوم یک سوم کاهش پیدا کند و احتیاجی به صفر کردن پراپرتی BottomPadding نیست .
زمانیکه ماوس از روی کنترل های فرم 2 جای دیگری منتقل می شود چنانچه سابفرم 3 اتفاع داشته باشد و BottomPadding مخالف صفر باشد کل باتن ها BottomPadding خود را از دست داده و پراپرتی ارتفاع سابفرم 3 نیز به صفر تنظیم میشود ( از رویداد MouseMove در سکشن Detail که باتن های فرم 2 در آن قرار دارند استفاده شده )
طبق جدول کامندهای Sub ( فرم ۳ ) به ترتیب از صفر به بعد نوشته شده و در هیچکدام از قلم افتادگی وجود ندارد به این نکته نیز توجه داشته باشید !!!
نمایش منوبار بعد از کلیک کردن روی باتن در همان مختصات بعد از ساختن CommandBar از مجموعه ی DLL های متصل به اکسس ، ولی قابلیت چپ چین شدن رو ندارند بنابراین در پروژه های فارسی کاربردی ندارند.
Public objPopup As Object
Private Sub Command13_Click()
Set objPopup = CommandBars("Menu Bar")
objPopup.ShowPopup
Set objPopup = Nothing
End Sub
بسیار ساده ولی پر دردسر
Btn0 Bt t1
Btn1 Btnt2
Btn2 Btnt3
Btnt4
طبق نام های بالا کنترل هایی از نوع باتن در فرم ساخته شده در کنار هم و زیر هم دقیقا مثل موارد فوق الذکر، تابعی نوشته شد که در زمان اتفاق افتادن رویدادکلیک باتنی از باتن های سمت چپ کل باتن های سمت راست به زیر آن انتقال یابد .
Function Btn(Bt As Control3) As Doble
For i=1 to 4
Controls("Btnt" & i).Left=Bt.Left+300
موقعیت پراپرتی TOP هر یک از کنترل های سمت راست میشود ( فرضا Btnt1 میشود Btn0.Top به اضافه ی عرضش و Btnt2 میشود Btn0.Top + Btn.Height +Btnt2.Height
Controls("Btnt" & i).Top=Bt.Top+Bt.Height+(i-1)*Controls("Btnt" & i).Height
(Btn=Controls("Btnt4".Top
Next
یا بصورت زیر
Function Btn(Bt As Control) As Double
b = Bt.Top
For i = 1 To 4
Controls("Btnt" & i).Left = Btn0.Left+300
Controls("Btnt" & i).Top = b + Controls("Btnt" & i).Height * i
Btn = Controls("Btnt" & i).Top
Next
End Function
چنانچه هر یک Toppadding خودش را داشته باشه فرضا بین باتن های سمت راست هر کدام فواصل متغیری باشد باید آنها را هم در نظر بگیرید ولی معمولا باتن ها را بهم بچسبانید تا نیاز به کد نویسی اضافه تری نباشد.
در رویداد کلیک Btn0 میتوان نوشت که اولا Btnt ها زیر آن بیاید و Btn1 و Btn2 در زیر Btnt ها قرار گیرد
()Private Sub Btn0_Click
Btn1.Top = Btn(Btn0) + Btnt4.Height
Btn2.Top = Btn1.Top + Btn1.Height
End Sub
()Private Sub Btn1_Click
Btn1.Top=Btn0.Top+Btn0.Height
(Btn2.Top=Btn(Btn1
End Sub
()Private Sub Btn2_Click
Btn1.Top = Btn0.Top + Btn0.Height
Btn2.Top=Btn1.Top+Btn0.Height
(Call Btn(Btn2
End Sub
تست شده طبق فایل GIF زیر ، نام ها در کپشن باتن ها نوشته شد تا گیج کننده نباشد.
SELECT TOP 10 Rnd(Len([strLastName])) AS Expr1,strLastNameFROM tblEmployeesORDER BY Rnd(Len([strLastName])) DESC;
:Table
OrderID | Payment Type | Ship State/Province |
---|---|---|
1 | Check | IL |
2 | Check | NY |
3 | Credit Card | NY |
4 | Credit CardCredit | IL |
5 | Check | IL |
:Query
OrderID | Payment Type | Ship State/Province | expr1 |
---|---|---|---|
1 | Check | IL | -1 |
2 | Check | NY | -1 |
3 | Credit Card | NY | 0 |
4 | Credit Card | IL | 0 |
5 | Check | IL | -1 |
expr1: ([orders]![payment type]="check" And [orders]![ship state/province]="ny") Or ([orders]![ship
(" state/province]="il" And Not [orders]![payment type]="credit card
طبق کوئری بالا و عبارت Expr1 رکورد یک : چون در اینجا بهم ریختگی هنگام نمابش وجود دارد جای نقطه پرانتز بگذارید
(pay="Check" (True ) And State="ny" (False) Or ..... State="il" (True) And Not Pay="Credit Card (True
.True And False. Or .True And True.
False Or True
True =-1
طبق کوئری بالا و عبارت Expr1 رکورد سه :
(pay="Check" (False ) And State="ny" (True) Or ..... State="il" (False) And Not Pay="Credit Card (False
.False And True. Or .False And False.
False Or False
Flase=0
طبق کوئری بالا و عبارت Expr1 رکورد چهار :
(pay="Check" (False ) And State="ny" (False) Or ..... State="il" (True) And Not Pay="Credit Card (False
.False And False. Or .True And False.
False Or False
Flase=0
:Query
OrderID | Payment Type | Ship State/Province | expr1 |
---|---|---|---|
1 | Check | IL | -1 |
2 | Check | NY | -1 |
4 | Credit CardCredit | IL | -1 |
5 | Check | IL | -1 |
مثال دوم :
:Query
OrderID | Payment Type | Ship State/Province | expr1 |
---|---|---|---|
1 | Check | IL | -1 |
2 | Check | NY | -1 |
3 | Credit Card | NY | 0 |
4 | Credit Card | IL | 0 |
5 | Check | IL | -1 |
6 | Check | NX | 0 |
7 | Check | NZ | 0 |
8 | Check | IL | -1 |
expr1: ([orders]![payment type]="check") And ([orders]![ship state/province]="ny" Or [orders]![ship
(" state/province]="il
طبق Expr1 در گرید بالا :
رکورد یک
(Pay="Check" (True) .... And State="ny" (False) Or State="il" (True
.True And .False Or True
True And True
True=-1
رکورد دو
(Pay="Check" (True) .... And State="ny" (True) Or State="il" (False
.True And .True Or False
True And True
True=-1
رکورد 6
(Pay="Check" (True) .... And State="ny" (False) Or State="il" (False
.True And .False Or False
True And False
False=0
:Query
OrderID | Payment Type | Ship State/Province | expr1 |
---|---|---|---|
1 | Check | IL | 0 |
2 | Check | NY | -1 |
3 | Credit Card | NY | -1 |
4 | Credit Card | IL | 0 |
5 | Check | IL | 0 |
6 | Check | NX | 0 |
7 | Check | NZ | 0 |
8 | Check | IL | 0 |
expr1: ([orders]![payment type]="check" Or [orders]![payment type]="credit card") And [orders]![ship
("state/province]="ny
رکورد اول
pay="check" True Or Pay="Credit Card" False.... And State="ny" False
True Or False. And False.
True And False
False=0
رکورد دوم
pay="check" True Or Pay="Credit Card" False.... And State="ny" True
True Or False. And True.
True And True
True=-1
OrderID | Payment Type | Ship State/Province | expr1 |
---|---|---|---|
2 | Check | NY | -1 |
3 | Credit Card | NY | -1 |
وقتی تکست 1 با لیبل "کد از " و تکست 3 با لیبل "کد تا " نال باشد
[Between [forms]![Form2]![Text1] And [forms]![Form2]![Text3?
Null
([isnull([forms]![Form2]![Text1?
True
[isnull([forms]![Form2]![Text3)?
True
( null or ( True or true?
True
جواب آخر True شد پس کل داده ها در دیتیل کانتینیوس فرم نمایش داده میشود
به تکست 1 داده 100 که در جدول از نوع نامبر است داده میشود خروجی به ترتیب زیر است
[forms]![Form2]![Text1]?
100
[forms]![Form2]![Text3]?
Null
[Between [forms]![Form2]![Text1] And [forms]![Form2]![Text3
Null
([isnull([forms]![Form2]![Text1?
False
([isnull([forms]![Form2]![Text3?
True
( null or ( False or true?
True
اگر در تکست 1 عدد 100 و در تکست 3 عدد 103 وارد شود
[forms]![Form2]![Text1]?
100
[forms]![Form2]![Text3]?
103
[Between [forms]![Form2]![Text1] And [forms]![Form2]![Text3
100
([isnull([forms]![Form2]![Text1?
False
([isnull([forms]![Form2]![Text3)?
False
False or False?
False
false Or 100?
100
The Change event occurs when the contents of the specified control change
زمانی اتفاق می افتد که محتویات کنترل مشخص شده تغییر یابد
فرضا فرمی دارید و یکسری داده ها را از جدول به کنترل ایجادشده واکشی کرده اید ( یعنی کنترل ها Bound شده هستند ) و داده ها بصورت Continous در گرید بنمایش گذاشته میشود ( در سکشن Detail ) حال در Form Header تکست باکسی تعبیه کرده اید با نام text5 که Unbound است . در کویری بیلدر فرم که میتوانید در RecordSource در پراپرتی شیت در نمای دیزاین بدان دست یابید در قسمت فیلد نام و نام خانوادگی در Criteria نوشته اید "*" & Forms!Form1!text5 ( تکست ۵ در فرم هدر ساخته شده ) برای اینکه همزمان با تایپ کاراکتر در تکست ۵ منبع فرم ریکوئری شود در رویداد Change آن تکست باکس می نویسید
Me.Requery
اگر به همین بسنده کنید بعد از تایپ حرف منبع ریکوئری شده با توجه به شرطی که در کوئری قرار داده شده و فوکس به اولین کنترل در دیتیل انتقال داده می شود . در نتیجه باید فوکس را دوباره به text5 منتقل کنیم در نتیجه
Me.text5.SetFocus
چانچه عبارت زیر نوشته نشود حروف تاپ شده در همان Space اول درجا میزند یعنی حرف بعدی جایگزین حرف قبلی میشود و باصطلاح به Space بعدی منتقل نمیشود.
(Me.text5.SelStart=Len(Me.text5.text
توضیح در مورد پراپرتی SelStart :
عدد صحیح محدوده 0 تا مجموع کاراکترها در ناحیه تکست باکس کمبو باکس ( چون کمبو یک تکست باکس دارد و یک دراپ داون کنترل )
برای تنظیم یا برگشت این پراپرتی به یک کنترل ، کنترل باید فوکس داشته باشد . برای انتقال فوکی به یک کنترل متد SetFocud را بکار می برند
اگر SetFocus داده نشود اروری دریافت خواهید کرد که نبود آنرا متذکر خواهد شد طبق شکل زیر
You cannot reference a property or method for a control unless the control has the focus
بخصوص در فیلتر در کمبو باکس اتفاق می افتد
البته در این مورد چنانچه داده ها در دیتیل فرم باشند و نه در سابفرم زمانیکه تایپ می کنید Space Bar نمی گیرد ( یعنی Space بزنید ) و این مشکل بزرگیست . که معمولا با اضافه کردن KeyCode 32 و قرار دادن یک مقدار Boolean در رویداد Keycode دار و اعمال آن در رویداد Change تکست باکس برطرف میشود که اگر مقدار Boolean درست بود میشود
" " & Me.text5=Me.text5
در هر صورت کار درستی نیست و همان بهتر که باتنی در فرم ایجاد شود و فیلتر از طریق آن اعمال گردد و یا داده ها در سابفرم آورده شود و سابفرم در دیتیل فرم کشیده شود که این مشکل زدن Space هم در رویداد Change آن تکست باکس حل شود
در مورد پراپرتی Text در تکست باکس :
از این پراپرتی می توان برای تنظیم یا بازگشت مقدار موجود در TextBox استفاده نمود
در حالیکه کنترل فوکس دارد این پراپرتی محتوی داده تکست جاری در کنترل است .پراپرتی Value محتوی آخرین داده ذخیره شده است . وقتی فوکس به کنترل دیگری منتقل میشود داده ی کنترل آپدیت میشود و پراپرتی Value به این داده جدید اختصاص می یابد. تنظیم پراپرتی Text از دسترس خارج است تا زمانیکه دوباره آن کنترل فوکس بگیرد.اگر از کامند Save Record استفاده شود بدون انتقال فوکس پراپرتی Text و پراپرتی Value همچنان یکسان می مانند.
! Note
To set or return a control's Text property, the control must have the focus, or an error occurs. To move the focus to a control, you can use the SetFocus method or GoToControl action.
طبق نوت آفیس برای استفاده از پراپرتی Text کنترل باید فوکس داشته باشد یا اینکه ارور اتفاق می افتد برای انتقال فوکس از متد SetFocus یا اکشن GoToControl استفاده میشود .
Set oFolder = CreateObject("Shell.Application").Namespace(Path)
For I = 1 To 100
Debug.Print I & ": " & oFolder.GetDetailsOf(oFolder.Items.Item(File), I)
Next I
Filter a query based on data entered in a text box
برای باز شدن کوئری میتوان از ماکرو و اکشن OpenQuery استفاده کرد
نمونه ماکرو
باز کردن تکست فایل و استفاده از قابلیت های خواندن نوشتن و اضافه کردن در آن
,object.OpenTextFile (filename,iomode,create
format
:iomode argument
ForReading=1
ForWriting=2
Open a file and write to the end of the 'file. You can't'
read from this file '
ForAppending=8
:format argument
TristateUseDefault=-2 'System default
TristateTrue=-1 'Opens the file as Unicoe
TristateFalse=0 'Opens the file as ASCII
Sub OpenTextFileTest Const ForReading = 1, ForWriting = 2, ForAppending = 8 Dim fs, f Set fs = CreateObject("Scripting.FileSystemObject") Set f = fs.OpenTextFile("c:\testfile.txt", ForAppending, TristateFalse) f.Write "Hello world!" f.Close End Sub
تسهیل دسترسی متوالی به فایل
Methods of the TextStream Object
Property | Description |
Close | Closes an open TextStream file. |
Read | Reads a specified number of characters from a TextStream file and returns the resulting string. |
ReadAll | Reads an entire TextStream file and returns the resulting string. |
ReadLine | Reads an entire line (up to, but not including, the newline character) from a TextStream file and returns the resulting string. |
Skip | Skips a specified number of characters when reading a TextStream file. |
SkipLine | Skips the next line when reading a TextStream file. |
Write | Writes a specified string to a TextStream file. |
WriteLine | Writes a specified string and newline character to a TextStream file. |
WriteBlankLines | Writes a specified number of newline characters to a TextStream file. |
Properties of the TextStream Object
Property | Description |
AtEndOfLine | A Boolean indicating whether or not the file pointer is at the end of a line in the text file (used when reading character by character). |
AtEndOfStream | A Boolean indicating whether or not the file pointer is at the end of file (used when reading line by line). |
Column | The column number of the current character position in a TextStream file. |
Line | The current line number in a TextStream file. |
Method | Description |
CopyFile | Used to copy an existing file. |
CopyFolder | Used to copy an existing folder. |
CreateFolder | Used to create a folder. |
CreateTextFile | Used to create a text file. |
DeleteFile | Used to delete a file. |
DeleteFolder | Used to delete a folder. |
DriveExists | Used to determine whether a drive exists. |
FileExists | Used to determine whether a file exists. |
FolderExists | Used to determine whether a folder exists. |
GetAbsolutePathName | Used to return the full path name. |
GetDrive | Used to return a specified drive. |
GetDriveName | Used to return the drive name. |
GetFile | Used to return a specified file. |
GetFileName | Used to return the file name. |
GetFolder | Used to return a specified folder. |
GetParentFolderName | Used to return the name of the parent folder. |
GetTempName | Used to create and return a string representing a file name. |
MoveFile | Used to move a file. |
MoveFolder | Used to move a folder. |
OpenTextFile | Used to open an existing text file |
r = Range("A65536").End(xlUp).Row + 1 For Each FileItem In SourceFolder.Files 'Display file properties Cells(r, 1).Formula = FileItem.Name Cells(r, 2).Formula = FileItem.Path Cells(r, 3).Formula = FileItem.Size Cells(r, 4).Formula = FileItem.DateCreated Cells(r, 5).Formula = FileItem.DateLastModified r = r + 1 Next FileItem
("Set xls=CreateObject("Excel.Application
. . . . . . . Set Wbk=xls.Workbooks.Open
("Set xlsht=Wbk.WorkSheets("Sheet1
Dim db As Dao.DataBase
Dim rst As Dao.RecordSet
xlsht.Range("A2").Select
("Set rst=db.OpenRecordSet("Select * From Table1
rst.AddNew
rst.Fields("ColA2")=xlsht.Range("A2").Value
rst.Update
rst.Close
Set rst=Nothing
Set db=Nothing
در قرعه کشی می توان استفاده کرد
عبارت زیر برای تولید عدد صحیح در محدوده یک تا صد
:the expression to make the range 1..100
The general expression to generate a random integer
: in a particular range is
where intLower and intUpper are the lower and upper limits of the range
Generating a random value of True or False is also
: easy
()Private Sub CmdClear_Click
""= Me.lstData.RowSource
End Sub
()Private Sub Form_Timer
( Me.txtDigitOne = CInt(Rnd() * 9
( Me.txtDigitTwo = CInt(Rnd() * 9
( Me.txtDigitThree = CInt(Rnd() * 9
End Sub
در تب Home در گروه Sort & Filter روی Advanced و سپس در شورت کات منو روی Advanced Filter/Sort کلیک بنمائید
عبارت زیر را در expression تایپ نمائید در اولین ستون و اولین ردیف . تابع IIf بررسی میکند که آیا مقدار فیلد Null است و اگر چنین باشد بعنوان صفر عمل می کند . اگر مقدار Null نباشد تابع IIf تابع Val را برای بدست آوردن معادل عددی آن فراخوانی میکند.
در سل Sort انتخاب کنید Ascending نمایش بصورت صعودی یا Descending نمایش بصورت نزولی
Private colPrimaryKeys As VBA.Collection
توابع windows/win32/kernel32/api/index.htm
تعداد میلی ثانیه هایی که از زمان شروع کار سیستم باقی مانده اند ، را تا 49.7 روز بازیابی می کند. در سیستم 64 بیت
Declare PtrSafe Function GetTickCount Lib "kernel32.dll" () As Long
در مثال زیر دیتاهایی در جدولی بنام Table1 رکورد شده و فیلد سوم هر گروه ( Line+Joint ) بصورت سورت id پشت سر هم به جدول Table2 ارسال و در آنجا ذخیره میشود
با کوئری نمی توان اینکار را انجام داد در نتیجه مجبوریم از Recordset استفاده کنیم.
1-نوشتن ساختار Sql جهت سورت نمودن رکوردهای جدول Table1 آنهم به این علت که رکوردهای هر گروه بصورت پراکنده در جدول ثبت شده.
"sSql="Select * From Table1 Order By Line,Joint,id
2-ایجاد کردن در حافظه ی موقت و باز کردن رکوردست در حالت SnapShot
(Set rst=db.OpenRecordSet(sSql,dbOpenSnapShot
3-رفتن به اولین رکورد و ذخیره کردن داده های Line Joint Re از Table1 در متغیرهای st1 st2 st3
rst.MoveFirst
st1=rst!Line
st2=rst!joint
st3=rst!re
4-رفتن به رکورد بعدی که حتما نوشتن این قطعه الزامیست
rst.MoveNext
در این مرحله در رکوردست لوپ زده میشود تا زمانیکه به انتهای آن برسد (EOF) داخل لوپ اگر st1=rst!Line و st2=rst!joint بود بایستی ستون re در هر تعدادکه بود پشت سر هم الصاق شوند و در متغیر st3 ذخیره شود
st3=st3 & ", " & rst!re
در غیر اینصورت دیتای ذخیره شده در این سه متغیر یعنی st1 st2 st3 در جدول Table2 اضافه یا اپند شود با ساختار Sql و استفاده از Insert Into و در نهایت قبل از بسته شدن if دوباره دیتاهای Line joint re در این متغیرها ذخیره گردند و به رکورد بعدی با rst.MoveNext این حلقه ادامه پیدا میکند در آخر یک رکورد در Table2 اپند نمی شود بعلت MoveNext اول که بعد از بستن Loop باید دوباره آن Sql که برای اپند کردن نوشته شده دوباره اجرا شود برای سرعت کار اپند کردن حتما از متد Database.Execute استفاده کنید و نه از Docmd.RunSql چرا که در رکوردهای حجیم مدت زمان بیشتری طول خواهد کشید البته نوشتن ساختار درست Sql هم باعث بالارفتن تقریبی سرعت خواهد شد .
"('" & sSql="Insert Into Table2(Line,joint,re) Values('" & st1 & "','" & st2 & "','" & st3
db.Execute sSql
حال شرح کد بالا به زبان ساده فرض کنید سورت شده ی جدول ۱ که با ساختار زبان sql در رکوردست باز شده ( مرحله ۲ ) طبق زیر باشد
Line joint re
A1 1 Rs
A1 1 Rt
A2 4 r1
st1=A1
st2=1
st3=Rs
از رکورد بعدی شروع میکند اگر نکند در آخر جواب میشود A1 1 rsrsrt یعنی Rs دوبار تکرار میشود
MoveNext
Do While.......Loop
if A1=A1 And 1=1Then
st3=st3 & ", " & Rs
در نهایت st3 در اینجا با رفتن به رکوردهای بعد در گروه A1 1 طبق MoveNext در انتهای Loop میشود st3=RsRt
Else
Append Query
st1=A2
st2=4
st3=r1
End if
MoveNext
چون در قبل از لوپ MoveNext قید شده در نتیجه به انتهای فایل میرسد و باید یک کوئری اپند دیگر برای St1=A2 st2=4 ,st3=r1 نوشت
اجرای Action Query یا Sql و سرعتش از Docmd.runsql بیشتر است و فقط روی Action Query ها قابل اجراست در غیر اینصورت ارور خواهد داد
اکشن کوئری مثل اپند ، دیلیت یا کوئری آپدیت
اگر با رکوردست کار می کنید و لوپ می زنید که کاری انجام شود در حجم زیادی از رکوردها برای سرعت انجام کار از این روش استفاده بنمائید و اگربعد از آن dbfailonerror هم استفاده کنید از ارور صرفنظر میکند و فرآیند ادامه پیدا میکند
از پراپرتی RecordsAffected زمانی استفاده میشود که بخواهید تعداد رکوردهای متاثر از این عمل به شما برگردانده شود.