آموزش مبانی ویژوال بیسیک/تعریف متغیرها در ویژوال بیسیک

ویکی‎کتاب، کتابخانهٔ آزاد
آشنایی با برنامه نویسی به‌وسیله VB تعریف متغیرها در ویژوال بیسیک '
آموزش مبانی ویژوال بیسیک


به اطمینان، قبلاً در برنامه نویسی (لااقل در Basic که پیش فرض بحث ما معرفی شده بود) از متغیرها زیاد استفاده کرده‌اید. در برخی زبانهای برنامه نویسی (مثل Basic)، نوع متغیرهای بکار رفته در برنامه، لازم نیست از قبل تعریف شده باشد و در هنگام اجرا، کامپایلر، خود، آن را به نوع مورد نیاز (مثل Integer برای برای داده‌های عددی صحیح، یا String برای نوع داده رشته‌ای و کاراکتری و ...) تعریف و اجرا خواهد کرد. اما در برخی دیگر (مانند زبان برنامه نویسی Pascal)لازم است، نوع داده متغیرهای بکار رفته، در جایی از برنامه (و عموماً قبل از استفاده از آن) تعریف شوند. در VB، از آنجا که VB از Basic برای کدنویسی استفاده می‌شود، به طور معمول، نیاز به تعریف نوع داده‌ها نیست. اما از آنجا که امروزه برنامه نویسان ترجیح می‌دهند که از کامپایلری برای برنامه نویسی استفاده کنند که او را به تعریف تمام متغیرها مجبور کند (زیرا اگر چنین نباشد، اگر او به اشتباه دستوری را غلط تایپ کند (مثلاً بجای then بنویسد Then)، کامپایلر آن را به عنوان متغیری فرض می‌کند و در واقع بدون اینکه ما خطایی را دریافت کنیم، در روند برنامه مان مشکل پیدا می‌شود و خطایی رخ می‌دهد که شاید تشخیص علت آن سخت تر شود)، می‌توانیم VB را موظف سازیم تا ما را مجبور به تعریف نوع داده متغیرها نماید.

اگر در ابتدای هر یونیت (Unit) عبارت Option Explicit نوشته شود، VB ما را مظف می‌کند که در آن یونیت، هر متغیری که بخواهیم استفاده کنیم، آن را قبل از استفاده، تعریف نماییم (لذا بهتر است ابتدای همه Unitها عبارت مذکور باشد). یونیت (Unit)ها، بخش‌هایی از برنامه‌اند که در آنها کدنویسی می‌شود. مثلاً هر فرم، دارای یک Unit مخصوص به خود است که تمام Event Procedureهایی که تا بحال می‌نوشتیم، در آن قرار می‌گرفت. همچنین اگر از منوی Tools گزینه Options را اتنخاب کنیم، و از لبه General (Tab Sheet)، گزینه Require Variable Declare را چک مارک بزنیم، از این پس، VB هر فرمی که ایجاد می‌شود، به طور پیش فرض عبارت Option Explicit را در ابتدای آن خواهد نوشت و در واقع همیشه ما را موظف می‌سازد که متغیرها را تعریف نماییم. برای تعریف متغیرها از دستور Dim به شکل کلی زیر استفاده می‌شود: Dim variableNames As variablsType به عنوان مثال دستور Dim a,b As Integer متغیرهایی را به نام a,b از نوع داده Integer (نوع داده عددی صحیح) تعریف می‌کند و سپس از آن می‌توانیم متغیر a را در برنامه مقداردهی نماییم. متغیرها را می‌توان در سه سطح تعریف نمود

Space of Variables- ۱- سطح پروسیجر (procedure Level): اگر متغیری در یک Procedure (و معمولاً ابتدای آن) تعریف کنیم، آن متغیر را فقط در همان Procedure می‌توان استفاده نمود و در واقع برای همان Procedure خاص تعریف شده است.

۲- سطح فرم (Form Level) :در سطح فرم (یعنی در ابتدای Unit مربوط به فرم و پس از عبارت Option Explicit)، متغیرها می‌توانند به دو نوع تعریف شوند: ۲-۱- تعریف به صورت Private (شخصی):

 اگر متغیری در سطح فرم به صورت Private و به شکل کلی:

Private variableNames As variableType

 تعریف شود، آن متغیر فقط در تمام Procedureهای فرم قابل استفاده است و در فرم‌های دیگر قابل دسترسی و استفاده نمی‌باشد (مگر اینکه در آنها هم جداگانه تعریف شده باشد).

۲-۲- تعریف به صورت Public (عمومی):

 اگر متغیری در سطح فرم، به صورت Public و به شکل کلی:

Public variableNames As variableType تعریف شود، در این صورت آن متغیر علاوه بر دسترسی در همان فرم (بوسیله نام آن متغیر)، در فرمهای دیگر (در واقع در کل پروژه) قابل دسترسی خواهد بود. فقط در صورت نیاز به استفاده در فرمهای دیگر لازم است نام فرمی را که متغیر در آن تعریف شده است ذکر شود (البته اگر آن فرم load باشد) و سپس پس از یک نقطه (Dot) نام آن متغیر آورده شود. به عنوان مثال اگر در ابتدای یونیت مربوط به Form1 نوشته شده باشد: Public Number As Integer و بخواهیم در فرمی دیگر، به آن مقداردهی کنیم، لازم است چنین بنویسیم: Form1.Number = ۱۵ توجه: اگر در سطح فرم از Dim برای تعریف استفاده شود، به طور پیش فرض آن را Private در نظر خواهد گرفت.

۳- سطح ماژول (Module Level): ماژولها بخشی از پروژه هستند که متغیرها، توابع و Procedureهای عمومی (Global) را در آن تعریف می‌کنیم. اگر تعریفی (مثل تعریف نوع داده متغیر یا یک Procedure) با Private انجام گیرد، فقط در همان ماژول قابل استفاده می‌باشد و اگر با Public صورت گیرد، در هر فرمی و بدون نیاز به نوشتن نام ماژول در ابتدای آن، قابل استفاده خواهد بود. نکته‌ای که باید توجه داشت اینکه اگر بخواهیم از متغیریا Procedureای که در یک ماژول به صورت Public تعریف شده است، در ماژولی دیگر استفاذه کنیم، ذکر نام ماژول در ابتدای آن به همراه یک نقطه (Dot) ضروری است. معمولاً از تعریف Public در ماژول زمانی استفاده می‌کنیم که بخواهیم متغیر یا Procedureای به صورت Global (عمومی) در سراسر پروژه استفاده شود. شاید بگویید می‌شود در هر فرمی که به آن نیاز داریم، همانجا متغیر را تعریف می‌کنیم، پس چه نیازی به ماژول داریم؟ هر چند این کار باعث می‌شود که برنامه خطای دستوری از ما نگیرد اما در اینصورت وقتی از فرمی به فرم دیگر می‌رویم مقدار موجود در آن متغیر، پس از تعریف مجدد، دوباره Null (تهی) می‌شود، در حالیکه اگر از یکبار تعریف Public در ماژول استفاده کنیم، پس از مقدار دهی در جایی از پروژه، تا مقداردهی مجدد، این مقدار در تمام پروژه قابل دسترسی است. برای افزودن یک ماژول به پروژه کافی است از منوی Project گزینه Add Module را انتخاب کنید و آن را (با پسوند .BAS) save نماییم. همانطور که ملاحظه می‌فرمایید، ماژولها تنها بخش کدنویسی (Unit) دارند بر خلاف فرمها که یک بخش Interface (ظاهری) داشتند که کنترلها را به صورت Visual روی آن قرار می‌دادیم و یک بخش کدنویسی (Unit) که کدهای مربوط به Event Procedureها را در آن می‌نوشتیم. همچنین ملاحظه می‌فرمایید که با توجه به وظیفه ماژولها، معمولاً در کل پروژه اولاً به یک ماژول نیازمندیم ثانیاً به بیش از یک ماژول احتیاجی پیدا نمی‌کنیم. نکته: علاوه بر متغیرها می‌توانیم از ثوابت (Constants) نیز در پروژه استفاده کنیم. ثوابت، بخشی از پرونده‌اند که هنگام تعریف، مقداردهی می‌شوند و تا پایان پروژه مقدارشان ثابت می‌ماند. برای تعریف ثوابت از دستور Constant استفاده می‌شود به عنوان مثال: Const PI As single = ۳٫۱۴

ایجاد پروسیجر در VB، علاوه بر Event Procedureها که به ازای رویداد (Event)های مشخصی انجام می‌شوند، می‌توانیم تعدادی پروسیجر را نیز خودمان تعریف کنیم که به این نوع پروسیجر، General Procedure (پروسیجر عمومی) گفته می‌شود که برای اجرای آنها می‌بایست نام آنها در جایی از برنامه، فراخوانی شود. در VB (مشابه Basic) دو نوع پروسیجر داریم: ۱- تابع (Function) ۲- روال (Sub). توابع قطعه برنامه‌هایی هستند که هرگاه نام آنها در برنامه فراخوانی شود، لزوماً یک و فقط یک مقدار را به عنوان خروجی برمی گرداند در حالی که روال (ساب روتین)ها، قطعه برنامه‌هایی هستند که ممکن است به تناسب دارای یک یا چند خروجی و یا حتی بدون خروجی باشند. توابع و روالها می‌توانند شامل تعدادی آرگومان (پارامتر) باشند که پارامترها در توابع فقط نقش ورود اطلاعاتی از برنامه به تابع را ایفا می‌کنند و نام خود تابع به عنوان خروجی تابع استفاده می‌شود در حالی که در روالها ورود و خروج داده‌ها، هر دو توسط همین پارامترها انجام می‌شود. شکل کلی توابع به شکل زیر است: Function functionName (Parameters) As variableType

Commands End Function و همچنین شکل کلی روال‌ها: Sub subName (Parameters) نکاتی درباره پروسیجرها توجه داشته باشید که در ابتدای تعریف توابع و روالها می‌توانیم از Private یا Public نیز استفاده کنیم و تمام سطوحی که برای تعریف متغیرها گفته شد (خصوصاً سطح فرم و سطح ماژول)، در اینجا نیز عیناً کاربرد دارند. (پیش فرض در اینجا هم Private است). به عنوان مثال اگر بخواهیم تابعی به نام Square ایجاد نماییم که هر عددی را دریافت کرد، مربع آن را برگرداند، کافی است چنین بنویسیم (مثلاً به صورت Public در یک ماژول):

Public Function Square (I As Integer) As Integer

 Square = I*I

End Function

ملاحظه می‌کنید که در اینصورت اگر هر جایی از برنامه نام تابع را به همراه یک مقدار عددی Integer به عنوان پارامتر آن ذکر کنیم، مقدار عددی مذکور به متغیر I داخل تابع منتقل شده و عمل I*I روی آن انجام می‌گیرد و از آنجا که گفتیم خرجی توابع نام آنها هستند، خروجی (یعنی مقدار I*I را) را به نام تابع جایگزین کردیم (یعنی Square = I*I). حال مثلاً اگر در جایی از برنامه دستور b = Square (5) را وارد کنیم، مقدار متغیر b برابر ۲۵ خواهد شد. توجه داریم که اگر تابع بیش از یک پارامتر ورودی داشت، باید نام آنها با کاما (,) از هم جدا کنیم که در اینصورت در هنگام فراخوانی باید به تعداد پارامترها، آرگومان قرار دهیم که به ترتیب در متغیر مربوط جایگزین (وارد) می‌شود. مثلاً اگر بخواهیم تابعی به نام Multiple ایجاد کنیم که حاصلضرب دو پارامتر ورودی اول را با پارامتر ورودی سوم جمع کند و نتیجه را برگرداند، کافی است بنویسیم:

Private Function Multiple (a, b, c As Integer) As Integer

 Multiple = (a*b) +c

End Function

که در اینصورت دستورات زیر در محلی از پروژه (که البته دسترسی Private به تابع مذکور داشته باشد)، مقدار ۱۷ را در Text Box به نام txtResult قرار می‌دهد:

I = ۳ bs = ۵ g = ۲ txtResult.Text = Multiple (I, bs, g)

توجه داریم که مقادیر استفاده شده به عنوان آرگومانهای تابع باید با متغیرهای به کار رفته در پارامترهای تعریف تابع از لحاظ نوع داده، یکسان باشند. حال به عنوان مثالی برای روالها فرض کنید بخواهیم روالی به نام TF ایجاد کنیم که دو عدد را دریافت کند، بررسی کند که اگر این دو عدد برابر بودند، جواب True و همچنین حاصلضرب آن دو را برگرداند. برای این منظور اگر مثلاً در یک ماژول تعریف کنیم:

Public Sub TF (x, y As Integer, T as Boolean, M as Integer)

 IF x = y then
 T = True
 Else
 T = False
 End IF
 M = x*y

End Sub

می‌توان در جایی از پروژه، روال مذکور را فراخوانی نمود، فراخوانی روالها توسط دستور Call صورت می‌گیرد، مثلاً اگر در جایی از پروژه، روال فوق را به صورت زیر فراخوانی نماییم:

a = InputBox (“Please Enter a Number”) Call TF (a, 15, s, p)

در صورتی که متغیرهای a و s و p تعریف شده باشند آرگومان a به پارامتر x از روال، آرگومان ۱۵ به پارامتر y از روال، آرگومان s به پارامتر T از روال و آرگومان p به پارامترM از روال منصوب می‌شود. دستور InputBox یک جعبه محاوره‌ای برای کاربر نشان می‌دهد که پیغامی را (در اینجا پیغام Please Enter a Number) شامل می‌شود و در یک جعبه متن خاص، مقداری را از کاربر مطالبه می‌کند که پس از وارد کردن توسط کاربر مقدار وارد شده را برمی گرداند (و در اینجا در متغیر a جایگزین می‌کند). حال اگر کاربر مقدار ۱۵ را وارد کند، مقدار متغیر s (که باید Boolean تعریف شده باشد) برابر True و در غیر اینصورت مقدار False را شامل می‌شود و در هر صورت متغیر p نیز حاصلضرب a و ۱۵ را در خود شامل می‌شود. تأکید می‌کنیم که نوع داده آرگومانها و پارامترهای تعریف لزوماً باید به ترتیب متناسب باشد که در غیر اینصورت VB به ما خطا صادر می‌کند. کنترل‌های Check Box و Option Button

Commands

End Sub

به اطمینان، از زمانی که با ویندوز کار می‌کنید، از کنترلهای Check Box و Option Box استفاده بسیاری برده‌اید. اگر بخواهیم به کاربر (User) این امکان را بدهیم که از بین چند گزینه، یک، دو یا چند مورد را انتخاب کند و یا حتی هیچ‌یک را انتخاب نکند از کنترل Check Box به شکل (۱)، و اگر بخواهیم کاربر، از میان چند گزینه، یک و فقط یک گزینه را انتخاب کند، از کنترل Option Button (کلیدهای رادیویی) به شکل (۲)، این دو کنترل VCL، مشخصه‌ای به نام Value دارندکه از صفر یا یک بودن مقدار آن، می‌توانیم به انتخاب نشده بودن و انتخاب شده بودن آن گزینه خاص، پی ببریم؛ لذا اگر برروی یک فرم چند Check Box وجود داشت، می‌تواند Value هر یک از آنها صفر یا یک باشد، اما اگر برروی فرمی، چند Option Button وجود داشت، تنها یکی از آنها می‌تواند Value برابر یک داشته باشد و وقتی کاربر، یکی دیگر را انتخاب می‌کند، به طور خودکار، Value قبلی صفر و Value کنترل انتخاب شده، یک می‌شود. VB دارای دو ثابت (Constant) به نامهای VBChecked و VBUnchecked می‌باشد که به ترتیب برابر یک و صفر می‌باشند که می‌توانیم مقدار Value کنترلهای ذکر شده را با این ثوابت مقایسه کنیم. کنترل Check Box، علاوه بر دو مقدار صفر و یک برای مشخصه Value، مقدار برابر ۲ نیز برای آن دارد که اگر به آن Set شود، این کنترل، خاکستری رنگ (Gray) می‌شود که معمولاً در ویندوز نشان از پیش فرض بودن دارد. همچنین کنترل مذکور، مشخصه‌ای هم به نام Style دارد که اگر مقدار آن را از صفر به یک تغییر دهیم، شکل Check Box به شکل دکمه‌ای در می‌آید که یک بودن مقدار Value، باعث فشرده شدن کلید و صفر بودن آن باعث بالا بودن کلید می‌شود. نکته آخری که در اینجا متذکر می‌شوم اینست که طبق قراری که از ابتدا گذاشته بودیم، سه حرف اول مشخصه Name کنترلها بهتر است متناسب با کنترل بگذاریم. برای Check Boxها، نام را با chk و برای Option Buttonها، نام را با opt آغاز می‌کنیم و ادامه نامشان را معمولاً با Caption آنها کامل می‌کنیم. لازم است ذکر شود که مشخصه Caption هر دو کنترل مذکور، حاوی آن عبارتی است که کنار آن کنترل برای معرفی آن به کاربر می‌آید.

فرض کنید بخواهیم فرمی شامل یک Text Box و دو Check Box با عنوانهای Bold و Italic داشته باشیم که اگر Bold، مارک خورده بود، متن داخل Text Box به صورت Bold درآید و اگر Italic مارک خورده بود به صورت Italic فرم نهایی آن را در شکل ۶ می‌توانید ببینید.

Private Sub chkBold_Click ()

 IF chkBold.Value = VBchecked Then
 txtDisplay.FontBold = True
 Else
 txtDisplay.FontBold = False
 End IF

End Sub

Private Sub chkItalic_Click ()

 IF chkItalic.Value = VBchecked Then
 txtDisplay.FontItalic = True
 Else
 txtDisplay.FontItalic = False
 End IF

End Sub

توجه داشته باشیم که هرگاه کاربر بر روی یک Check Box و یا یک Option Button کلیک کند و یا بوسیله کلید Tab، فوکوس را به آن دهد و روی آن کلید Space bar را بزند، رویداد Click از این دو کنترل روی خواهد داد. آرایه‌ای از کنترلها حتماً یکی از الفاظی که در برنامه نویسی، از آن بهره بسیاری برده‌اید، آرایه می‌باشد. آرایه‌ها معمولاً خانه‌هایی از حافظه‌اند که تحت یک نام واحد و با اندیس‌های متفاوت نامگذاری می‌شوند. در Basic هم آرایه‌ها (مانند سایر زبانهای برنامه نویسی) کاربرد فراوانی دارند که مثلاً توسط دستور Dim A (10, 10) As Integer یک آرایه دو بعدی (در واقع یک ماتریس) به نام A از نوع داده Integer تعریف می‌شود که سطر وستون آن دارای اندیس‌های ۰ تا ۱۰ می‌باشد و توسط مثلاً A (5, 8) به خانه سطر ۵ و ستون ۸ از آن دسترسی خواهیم یافت. در VB نیز (از آنجا که VB از Basic برای کدنویسی استفاده می‌کند)، آرایه‌ها، تعریف آنها و نحوه دسترسی به خانه‌های آن به طریق فوق می‌باشد. اما آنچه در اینجا متفاوت است اینکه در VB می‌توان از کنترلها نیز یک آرایه ساخت. مثلاً چند Command Button با یک نام خاص و با اندیسهای متفاوت ایجاد کرد تا بتوان کدهای واحدی را با تفاوت بسیار کم برای همه شان نوشت. اگر از یک کنترل کپی کنیم (در حالی که فوکوس در Design Time به آن است، کلیدهای CTRL+C را فشار دهیم) و سپس آن را در همان فرم Paste نماییم (کلیدهای CTRL+V را فشاردهیم)، پیغامی بر روی صفحه نمایش ظاهر می‌شود مبنی بر اینکه "یک کنترل دیگر با همین نام در فرم وجود دارد، آیا می‌خواهید آرایه‌ای از کنترل ایجاد کنید؟" که می‌توانید جواب No به آن بدهید. اما اگر به این پیغام دکمه Yes را پاسخ دهید، VB به طور خودکار نام هر دو را یکسان (و به نام کنترل کپی شده) در نظر می‌گیرد و Index کنترل اول را صفر و Index کنترل دوم را یک قرار می‌دهد (Index، یکی از مشخصه (Property)های تمام کنترل‌ها می‌باشد). می‌توان اینکار را دستی نیز انجام داد. یعنی دو کنترل (یا چند کنترل) خاص را یک نام واحد دهیم که در اینصورت VB پس از دادن یک پیغام مبنی بر همین موضوع، آن دو کنترل (یا چند کنترل) را به صورت آرایه کنترل تبدیل خواهد کرد و به هر یک Index خاصی را نسبت خواهد داد. اگر آرایه کنترل ایجاد کنیم، هر رویداد (Event) ای که بر روی هریک از عناصر رخ دهد (مانند Click و غیره)، روی تمام آرایه صورت می‌گیرد و مقدار Index مربوط به عضوی که رویداد بر روی آن صورت گرفته، به عنوان یکی از پارامترهای پروسیجر آن، باز می‌گردد. برنامه بعد را بنویسید تا با نحوه کار آرایه کنترلها آشنا شوید. مثال: طراحی یک ماشین حساب ساده

فرض کنید بخواهیم یک ماشین حساب ساده، مطابق آنچه در شکل ۷ می‌بینید، طراحی کنیم:

یک Label به نام lblDisplay به عنوان نمایشگر ماشین حساب و با Caption برابر مقدار" ۰" (زیرا مقدار اولیه ماشین‌حساب‌ها صفر می‌باشد) در محل خود قرار می‌دهیم. همچنین یکCommandButtonبه نام cmdequal به عنوان دکمه مساوی" و با Caption برابر "= " نیز در محل مخصوص خود قرار می‌دهیم. حال ده عدد Command Botton دیگر با Captionهای به ترتیب برابر " ۰" تا "۹ " را در جای خود قرار می‌دهیم و سپس نام همه این ده دکمه را به نام cmdNumber تغییر می‌دهیم. در این صورت همانطور که گفته شد، VB این ده کنترل را به صورت آرایه کنترلی (Control Array) در نظر خواهد گرفت (به پیغام داده شده با همین مضمون جواب Yes دهید). به همین ترتیب چهار CommandButton دیگر را با Captionهای "+ " و "- " و "* " و "/ " و با نام یکسان cmdOprator به عنوان دکمه‌های چهار عمل اصلی به صورت آرایه کنترلی در محل‌های خود قرار می‌دهیم. حال کافی است در یونیت مربوط به این فرم، چنین کدنویسی کنیم (توجه داشته باشید که متغیرهای x و y و op در سطح فرم (Form Level) تعریف شده‌اند و لذا مقدار آن در تمام فرم قابل دسترسی خواهد بود):

Option Explicit Dim x,y As Integer Dim op As String

Private Sub cmdNumber_Click (Index As Integer)

 IF lblDisplay = “Ø” then lblDisplay = “”
 lblDisplay = lblDisplay + cmdNumber(Index).Caption

End Sub

Private Sub cmdOprator_Click (Index As Integer)

 x = Val(lblDisplay)
 op = cmdOprator(Index).Caption
 lblDisplay = “Ø”

End Sub Private Sub cmdEqual_Click ()

 y = Val (lblDisplay)
 Select Case op
 Case “+”
 lblDisplay = x + y
 Case “-”
 lblDisplay = x - y
 Case “*”
 lblDisplay = x * y
 Case “/”
 lblDisplay = x / y
 End Select

End Sub

توجه دارید که:

۱. در رویدادهایی که مربوط به آرایه‌های کنترلی (یعنی cmd Number و cmdoperator) است، یک پارامتر به نام Index در آن وجود دارد که شماره Index (اندیس) کلیدی که فشرده شده را برمی‌گرداند؛ و لذا مثلاً cmdOprator(Index).Caption برابر "+" خواهد بود، اگر کلید + فشرده شود و برابر "- " خواهد بود، اگر کلید – زده شود و ...

۲. مشخصه (Property) پیش فرض برای Labelها Caption است و لذا هر جا lblDisplay ذکر شده است، توسط VB مانند lblDisplay.Caption در نظر گرفته می‌شود.

۳. توسط دستور Select Case، یک متغیر (که نام آن جلوی دستور Select Case نوشته می‌شود) با مقادیر مختلفی (که جلوی دستورات Case بعدی نوشته می‌شود) چک می‌شود که اگر برابر هر یک از این مقادیر بود، دستور پس از همان Case اجرا می‌شود. مثالی دیگر: استفاده از Option Buttonها همانطور که قبلاً نیز ذکر شد، هرگاه بخواهیم کاربر (User) از بین چند مورد، یک و فقط یک مورد را انتخاب کند (مثلاً سؤال چهار گزینه‌ای و ...) از کنترل Option Button استفاده می‌کنیم. کنترل مذکور (مانند CheckBoxها) دارای مشخصه‌ای به نام Value می‌باشد که اگر مقدار آن برابر True باشد، انتخاب شده و در صورتی که برابر False باشد، انتخاب نشده خواهد بود؛ بنابراین اگر برروی فرمی مثلاً دو OptionButton قرار دهیم، مسلماً اگر مقدار Value از یکی را True کنیم، به طور خودکار مقدار Value برای دیگری False خواهد شد. زیرا فقط یکی از OptionBottonها را می‌توان انتخاب کرد. حال اگر بخواهیم OptionButtonها را روی یک فرم به صورت موضوعی دسته‌بندی کنیم و از هر دسته بتوانیم یکی را انتخاب کنیم، باید به تعداد دسته‌ها، کنترل Frame به شکل برروی فرم قرار دهیم و آنگاه OpiontButtonها را بر روی Frameها (نه با دابل کلیک بلکه با انتخاب کنترل OptionButton و قرار دادن آن بوسیله Drag & Drop روی Frame) قرار می‌دهیم و سپس می‌توان Caption مربوط به Frameها (آن چیزی که به عنوان تیتر در بالای هر فریم نوشته می‌شود) و OptionButtonها (آن چیزی که جلوی هر Option Button برای معرفی آن نوشته می‌شود) را به دلخواه تغییر داد.

یک Label به نام lblDisplay و دو فریم به نامهای fraProcessor و fraOS بر روی صفحه قرار می‌دهیم. بر روی fraProcessor (و بوسیله انتخاب کنترل و Drag & Drop بر روی فریم)، سه OptionButton به نامهای واحد optProcessor و با Captionهای Pentium، Pentium II و Pentium III قرار می‌دهیم. همچنین بر روی fraOS نیز سه OptionButton دیگر به نامهای واحد optOS و با Captionهای Windows98، Windows2000 و WindowsNT قرار می‌دهیم. (توجه داریم که در اینصورت دو Control Array به نامهای optProcessor و optOS ساخته‌ایم). حال کدهای زیر را در یونیت این فرم می‌نویسیم:

Option Explicit Dim proc As string Dim os As string

Private Sub Clicked ()

 lblDisplay = “You select” + proc + “and” + os

End Sub

Private Sub Form1_load ()

 optProcessor(Ø).Value = True
 optOS(Ø).Value = True

End Sub

Private Sub optOS_Click (Index As Integer)

 os = optOS(Index).Caption
 Call Clicked

End Sub

Private Sub optProcessor_Click (Index As Integer)

 proc = optProcessor(Index).Caption
 Call Clicked

End Sub

توجه داریم که

۱. روال clicked در برنامه فوق هرگاه فراخوانی شود پیغام مناسب را در lblDisplay نمایش خواهد داد.

۲. رویداد load برای یک فرم بلافاصله پس از load شدن آن فرم روی می‌دهد. در Event Procedure مربوط به رویداد load از Form1 در برنامه فوق، دستور داده‌ایم که اولین OptionButton هر فریم (با اندیس برابر صفر) را انتخاب شده نماید.

۳. در رویدادهای Click مربوط به آرایه‌های optOS و optProcessor دستور داده‌ایم که مقدار Caption هر OptionButtonای که کلیک شده را (توسط مثلاً optOS(Index).Caption) در متغیرهای os و proc قرار دهد و سپس روال Clicked که برای نمایش بر روی label بود را فراخوانی نماید شبیه‌سازی عمل Drag & Drop فرض کنید بخواهیم برنامه‌ای بنویسیم که ظاهری شبیه آنچه در شکل ۹ می‌بینید داشته باشد؛ و بتوانیم تصویر داخل PictureBox مبداُ (سمت چپ) را بوسیله Drag & Drop به PictureBox مقصد (سمت راست) منتقل کنیم.

شکل ۹ ابتدا دو PictureBox (که کنترل آن در ToolBox به شکل می‌باشد) را در مکانهای خود قرار داده و مشخصه Name آنها را picSource و picTarget می‌گذاریم. برای نمایش متنی که در پایین شکل ۹ می‌بینید نیز می‌توانیم از یک Label استفاده کنیم. PictureBoxها دارای مشخصه‌ای به نام Picture هستند که بوسیله آن می‌توانیم یک تصویر را در آن قرار دهیم. اگر بخواهیم این مشخصه را در زمان طراحی (Design Time) تنظیم نماییم، کافیست بر روی نام این مشخصه در پنجره Properties، دابل کلیک نماییم، یک پنجره محاوره‌ای باز می‌شود که می‌توانیم تصویر مورد نظرمان را بیاوریم و آن را انتخاب کنیم. (پنجره‌ای مانند پنجره‌های Open در ویندوز). اما اگر بخواهیم آن را در زمان اجرا (Run Time) تنظیم نماییم، باید این مشخصه را برابرتابع loadPicture() قرار دهیم که مسیر و نام تصویر مورد نظر به عنوان پارامتر این تابع قرار می‌گیرد. . اگر در پارامتر این تابع چیزی قرار نگیرد، مشخصه Picture را خالی می‌کند یعنی PictureBox مورد نظر را (در صورتی که دارای تصویر بوده) بدون تصویر می‌کند. حال مشخصه Picture از picSource را (در زمان طراحی) به تصویر دلخواه مورد نظر خود تغییر دهید و در واقع یک تصویر را در آن قرار دهید. شایان ذکر است که می‌توانید تصاویر فراوان مناسبی را مسیر Visual Studio>Common>Graphics دستگاه خود (در داخل مسیری که برنامه Visual Studio را در آن نصب کرده‌اید)، بیابید. به سراغ برنامه خود برویم، تا اینجا ظاهر (Interface) برنامه را ایجاد کردید. حال لازم است به کدنویسی برای آن بپردازیم؛ ولی قبل از آن توضیح در مورد چند رویداد را ضروری می‌دانم که عموماً غالب کنترلهای VCL دارای این رویدادها می‌باشند: رویداد MouseDown: زمانی برای یک VCL رخ می‌دهد که دکمه‌ای از ماوس را روی آن VCL فشار دهیم. رویداد MouseUp: زمانی برای یک VCL رخ می‌دهد که دکمه زده شده از ماوس را رها کنیم. رویداد MouseMove: زمانی برای یک VCL رخ می‌دهد که نشانگر ماوس را بر روی آن حرکت دهیم. رویداد DragOver: زمانی برای یک VCL رخ می‌دهد که VCL دیگری که در حال Drag شدن است را بر روی این VCL بیاوریم. رویداد DragDrop: زمانی برای یک VCL رخ می‌دهد که VCL دیگری که در حال Drag شدن است را بر روی این VCL، Drop (رها) نماییم. حال که با این رویدادها آشنا شدیم، کافیست کدهای زیر را در یونیت این فرم داشته باشیم:

Option Explicit

Private Sub picSource_MouseDown (Button As Integer,Shift As Integer,x As Single,y As Single)

 picSource.Drag vbBegineDrag

End Sub

Private Sub picTarget_DragDrop (Source As Control)
 PicTarget .Picture = picSource.Picture
 picSource.Picture = loadPicture()

End Sub

توجه داشته باشیم که وقتی رویداد MouseDown برای picSource روی می‌دهد، توسط متد Drag از picSource (یعنی توسط picSource.Drag) و به همراه پارامتر VbBeginDrag برای آن، عمل Drag آغاز می‌شود و در صورتی که عمل Drop شدن روی picTarget صورت بگیرد (یعنی اگر رویداد DragDrop برای آن رخ دهد)، تصویر داخل picSource به داخل picTarget منتقل می‌شود (بوسیله دستور picTarget.Picture = picSource.Picture) و سپس تصویر داخل picSource (بوسیله دستور ()picSource.Picture = loadPicture) حذف می‌شود؛ و بالاخره آخرین تذکری که در اینجا داده می‌شود اینکه مشخصه Picture برای PictureBoxها مشخصه پیش فرض (Default) می‌باشد و لذا مثلاً بجای pictarget.picture می‌توان از pictarget نیز استفاده کرد استفاده از منو در فرمها: لابد از اهمیت فوق‌العاده زیاد منوها در ویندوز مطلع هستید. منوها علاوه بر تنوع و زیبایی فرم‌ها، به شلوغ نشدن یک فرم توسط دکمه‌های زیاد نیز کمک می‌کنند. برای درست کردن منو برای یک فرم از MenuEditor که در منوی Tools قرار دارد استفاده می‌کنیم. همچنین MenuEditor یک دکمه فوری نیز بر روی میله ابزار استاندارد VB به شکل دارد که با کلیک بر روی آن نیز پنجره MenuEditor باز می‌شود. این پنجره مانند شکل ۱۰ می‌باشد:

شکل ۱۰ در پنجره مذکور کافیست عنوان منوی اول (مثلاMenu1) را در کادر Caption بنویسیم و مانند سایر objectهای VB به این منو هم یک نام (مثلاmnuMenu1) در کادر Name وارد کنیم. حال برای وارد کردن نام و عنوان منوی بعدی کافیست کلید Next را بزنیم. اما معمولاً منوی بعدی، آیتمی از منوی قبلی خواهد بود. اگر کلید را بزنیم، منوی جاری به عنوان زیر منوی قبلی محسوب خواهد شد. پس از وارد کردن اولین آیتم کافیست بوسیله دکمه Next آیتم‌های بعدی اولین منو را نیز وارد کنیم. اگر یکی از آیتم‌ها خود شامل زیر آیتم‌هایی بود باز هم می‌توان از کلید سود برد؛ و بالاخره برای اینکه به سراغ منوی دوم برویم لازم است از کلید به تعدادی استفاده کنیم که دیگر زیرمنوی یک منوی دیگر نباشد و به همین ترتیب سایر منوها و آیتمها را نیز نامگذاری و عنوان‌دهی می‌کنیم و ساختار مورد نظرمان را برای منوها ایجاد می‌کنیم؛ لذا اگر منوها را در MenuEditor طوری وارد کنیم که پنجره پایین MenuEditor مطابق آنچه در شکل ۱۰ می‌بینید، شود، انتظار داریم در هنگام اجرا، فرمی شبیه آنچه در شکل ۱۱ می‌بینید، حاصل شود:

شکل ۱۱ توجه داشته باشید که در MenuEditor علاوه بر آنچه تابه‌حال گفته شد: • دکمه Delete برای پاک کردن یک منو (یا آیتم) استفاده می‌شود. • دکمه Insert برای افزودن یک منو (یا آیتم) میان دو منو (یا آیتم) دیگر استفاده می‌شود • Check Boxهای Visible و Enable به ترتیب اگر انتخاب نشده شوند، منوی مذکور دیده نمی‌شود و یا اینکه فقط غیرفعال (و به رنگ خاکستری) خواهد شد. • Check Box با عنوان Checked اگر انتخاب شود، باعث خواهد شد تا کنار آن منو (آیتم) یک «چک‌مارک» دیده شود. (معمولا این مشخصه در Run Time و بر حسب نیاز تنظیم می‌شود) • توسط Shortcut می‌توانیم یک میانبر (Shortcut) برای یکی از آیتم‌ها درست کنیم.. • توسط Index می‌توانیم آرایه‌ای از منوها را طراحی نماییم (همانطوری که آرایه‌ای ازسایر کنترلها درست می‌کردیم، یعنی باید نام دو یا چند منو را یک نام واحد بگذاریم و Index متفاوت به هریک بدهیم) • و توسط NegotiatePosition می‌توان نوع چیدن آیتم‌ها (راست چین، چپ چین، وسط چین) را تعیین نمود. چند تذکر: • برای دستیابی به مشخصه‌های منوها نیز مانند سایر کنترلها از نام آنها و یک نقطه(Dot) و سپس نام مشخصه مورد نظر استفاده می‌کنیم. مثلاً اگر منویی به نام mnuOpen داشته باشیم و بخواهیم آن را غیرفعال و یا مارک‌دار نماییم به ترتیب از دستورات زیر استفاده خواهیم کرد:

mnuOpen.Enable = False mnuOpen.Checked = True

• مشخصه WindowList در بحث MDI Forms خواهد آمد و از مشخصه HelpContentID نیز تنها زمانی که یک فایل HLP داشته باشیم می‌توانیم استفاده کنیم. • اگر بخواهیم بین دو آیتم از منویی یک خط جداکننده آورده شود (آنچه در ویندوز برای جداکردن بخشهای مختلف یک منوی خاص معمول است) کافی است بین آن دو آیتم، یک آیتم Insert نماییم، نام آن را یک نام دلخواه (مثلا mnuLine) و عنوان (Caption) آن را یک منفی (کاراکتر "-" یا اصطلاحاً Dash) بگذاریم. • اگر بخواهیم برای شی خاصی یک PopUpMenu طراحی کنیم (منوهای بازشونده‌ای که وقتی بر روی شی کلیک راست شود از آن خارج می‌شود) کافیست یک منو (با آیتمهای مورد نظر برای آن) را طراحی کنیم (و حتی در صورت نیاز Visible آن را False کنیم) و در رویداد MouseDown از آن شی خاص، پس از اینکه شرط کردیم کلید زده شده کلید راست ماوس باشد (با استفاده از شرط برابری پارامتر Button از این رویداد با مقدار ثابت VbRightButton)، با استفاده از دستور PopUpMenu، نام منوی مورد نظر را فراخوانی می‌کنیم یعنی باید چنین داشته باشیم:

Private Sub controlName_MouseDown (Button As Integer,…)

 IF Button = VbRightButton Then
 PopUpMenu mnuMenu1
 End IF

End Sub

که بجای controlName نام آن کنترلی که قرار است کاربر روی آن کلیک راست نماید و بجای mnuMenu1 نام آن منویی که قرار است به صورت PopUp آورده شود را ذکر می‌کنیم اضافه کردن DialogBox به برنامه مطمئناً تا بحال در ویندوز از کادرهای محاوره‌ای زیادی مثل پنجره‌های Open، Save، نمایش خصوصیات چاپگر (Printer)، کادر انتخاب رنگ، کادر انتخاب Font و پنجره Help ویندوز استفاده کرده‌اید. در VBبرای نمایش اینگونه پنجره‌های محاوره‌ای از کنترل DialogBox استفاده می‌کنیم. این کنترل یکی از کنترل‌های Non - Visual ویژوال بیسیک می‌باشد. Non-Visual Controls همانطور که قبلاً هم آمده است، انواعی از کنترل‌ها هستند که فقط در زمان طراحی (Design Time) بر روی فرم دیده می‌شوند و در Run Run Time فقط می‌توان از اثر آنها بهره برد. کنترل مذکور بطور پیش فرض در ToolBar وجود ندارد. برای اضافه کردن آن به ToolBar باید از منوی Project گزینه Components را انتخاب کنیم و در لیست Componentها، گزینه Microsoft Common Dialog Control 6 را چک مارک بزنیم و آن را تایید (OK) نماییم. در اینصورت یک کنترل به شکل به ToolBar افزوده خواهد شد که می‌توانید آن را با دابل کلیک بر روی فرم قرار دهید. توجه داریم که کنترل مذکور Non-Visual است و لذا نیازی به تنظیم مکان این کنترل بر روی فرم ندارید. کنترل Dialog Box دارای متدهای زیر می‌باشد:

ShowColor برای نمایش پنجره محاوره‌ای تعیین رنگ در زمان فراخوانی این متد.

ShowFont برای نمایش پنجره محاوره‌ای تعیین فونت در زمان فراخوانی این متد.

ShowHelp برای نمایش پنجره محاوره‌ای راهنمای ویندوز در زمان فراخوانی این متد. ShowOpen برای نمایش پنجره محاوره‌ای باز کردن یک فایل در زمان فراخوانی این متد.

ShowPrinter برای نمایش پنجره محاوره‌ای تعیین خصوصیات چاپگر در زمان فراخوانی این متد.

ShowSave برای نمایش پنجره محاوره‌ای ذخیره کردن در یک فایل در زمان فراخوانی این متد.

Private Sub cmd_Click ()

 cdb.ShowColor
 lbl.ForeColor = cdb.Color

End Sub

یا اگر بخواهیم توسط دکمه‌ای دیگر به نام cmd2، پنجره Open باز شود، و هر فایلی از هر مسیری را که کار بر انتخاب کرد، در lbl نمایش داده شود، می‌نویسیم:

Private Sub cmd2_Click ()

 cdb.ShowOpen
 lbl.Caption = cdb.FileName

End Sub توابع MsgBox و InputBox از تابع MsgBox برای ارسال یک پیغام به کاربر و یا مطرح نمودن یک پرسش و دریافت جواب مثبت یا منفی او به سؤال مطرح شده و از تابع InputBox برای دریافت یک عبارت از کاربر، استفاده می‌شود. توابع مذکور را می‌توان مانند دستور نوشت، یعنی نام یکی از آن دو را و با یک فاصله پارامترهای احتمالی آنها را نوشت. همچنین می‌توان آنها را مانند یک Function به VB معرفی کرد. (یعنی این توابع دارای مقدار بازگشتی باشند) که برای این منظور باید پارامترهای آنها را داخل پرانتز نوشت. پنج پارامتر اول Input Box به ترتیب عبارتند از: Prompt: که یک عبارت رشته‌ای را (و یا یک متغیر رشته‌ای (String) را) بجای آن می‌نویسیم که این عبارت همان پیغامی خواهد بود که در اجرای InputBox به کاربر نشان داده خواهد شد (مثلاً پیغام اینکه او باید چه چیزی را وارد کند). Title: که عنوان InputBox در TitleBar آن خواهد بود (به صورت عبارت رشته‌ای). Default: که مقدار پیش فرض برای آن چیزی است که کاربر قرار است وارد نماید. XPos و YPos: که طول و عرض گوشه بالا و سمت چپ InputBox را در هنگام اجرای آن مشخص می‌کند؛ که می‌توان هریک از آنها را مقداردهی نکرد و در اینصورت مقادیر پیش فرض VB برای آنها در نظر گرفته خواهد شد. به عنوان مثال اگر دستورات:

Dim s As String s = InputBox (“Please enter your name” , “Title” , “Alireza”)

را در برنامه داشته باشیم در زمان اجرای این دستورات شکل ۱۲ را مشاهده خواهیم کرد:

شکل ۱۲ مشاهده می‌کنید که بطور پیش فرض مقدار “Alireza” در کادر مربوط قرار گرفته است که کاربر می‌تواند آن را تغییر دهد. در هر حال پس از تأیید این کادر توسط کاربر، آنچه در کادر مذکور باشد به عنوان نتیجه در متغیر رشته‌ای s ذخیره می‌شود و می‌توان از آن در ادامه استفاده نمود. اما سه پارامتر اول MsgBox نیز به قرار زیراند:

Prompt: که پیغامی است که در Message Box زمان اجرا به کاربر نمایش داده خواهد شد.

Button: که می‌توان دکمه‌های مورد نظر و علامت موردنظر برای Message Box را در آن تعیین نمود. برخی از مقادیر مهمی که می‌توان در این پارامتر قرار داد عبارتند از:

۱. VBOKOnly: کادر مذکور فقط دارای دکمه OK خواهد بود.

۲. VBOKCancel: کادر مذکور دارای دکمه‌های OK و Cancel خواهد بود.

۳. VBYesNo: کادر مذکور دارای دکمه‌های Yes و No خواهد بود.

۴. VBYesNoCancel: کادر مذکور دارای دکمه‌های Yes و No و Cancel خواهد بود.

۵. VBAbortRetryIgnore: کادر مذکور دارای دکمه‌های Abort و Retry و Ignore خواهد بود.

۶. VBRetryCancel: کادر مذکور دارای دکمه‌های Retry و Cancel خواهد بود.

۷. VBMsgBoxRight: در کادر مذکور Title را راست چین می‌کند.

۸. VBMsgBoxRtlReading: کادر مذکور را راست به چپ (Right to Left) می‌کند (و برای پیغام‌های فارسی مناسب است)

۹. VBCritical: یک علامت در کنار کادر اضافه خواهد شد.

۱۰. VBExclamation: یک علامت در کنار کادر اضافه خواهد شد.

۱۱. VBInformation: یک علامت در کنار کادر اضافه خواهد شد.

۱۲. VBQuestion: یک علامت در کنار کادر اضافه خواهد شد. نکته: می‌توان آنهایی را که با هم تداخلی ندارند با علامت + با هم ترکیب کرد. مثلاً اگر بخواهیم که هم دکمه‌های OK و Cancel بیایند و هم در کنار پیغام، علامت بیاید و هم Title راست چین شود، می‌توان در این پارامتر چنین نوشت:

VBOKCancel + VBInformation + VBMsgBoxRight

Title: که می‌توان عبارتی که در TitleBar این کادر می‌آید را مشخص نمود. به عنوان مثال اگر دستورات:

Dim Result As VbMsgBoxResult Result = MsgBox (“Are you sure you want to exit?”,vbQuestion+vbYesNo, “Exit”) IF Result = vbYes then Unload Me

را وارد کنیم، در اینصورت در زمان اجرای این دستورات ابتدا شکل ۱۳ به کاربر نمایش داده خواهد شد و در صورتی که کاربر به پیغام داده شده پاسخ Yes دهد، فرم فعال (که در VB با Me نمایش داده می‌شود)، Unload خواهد شد:

شکل ۱۳ توجه داریم که نتیجه تابع MsgBox از نوع داده vbMsgBoxResult می‌باشد و لذا ما در بالا متغیر Result را از این نوع داده تعریف کردیم. این نوع داده می‌تواند یکی از مقادیر vbAbort، vbCancel، vbIgnore، vbNo، vbOK، vbRetry و vbYes باشد