زهرا یک سری مقادیر صحیح در ستون A دارد. او می خواهد راهی را برای نشان دادن مقادیر فرد در ستون B و مقادیر زوج در ستون C. به ترتیب صعودی زهرا به این فکر می کند که آیا برای پردازش داده های خود به این روش به یک ماکرو نیاز دارد یا خیر.
پاسخ کوتاه این است که در واقع می توانید این کار را بدون توسل به یک ماکرو انجام دهید. با این حال، اگر نیاز به انجام این نوع پردازش زیاد دارید، ممکن است استفاده از ماکرو را سودمندتر بدانید.
ابتدا به رویکردهای غیر کلان نگاه می کنیم. در صورت تمایل میتوانید فرمولهای سادهای را در ستونهای B و C بنویسید که به سادگی بررسی کنید که آیا مقدار در ستون A فرد است یا زوج و اگر مناسب ستون است، مقدار را روی آن کپی کنید. به عنوان مثال، می توانید موارد زیر را در ستون B داشته باشید:
=IF(ISODD(A1),A1,"")
در ستون C، تنها کاری که باید انجام دهید این است که ISODD را با ISEVEN جایگزین کنید. وقتی این فرمولها را کپی میکنید، ستون B فقط حاوی مقادیر فرد و ستون C فقط مقادیر زوج است. البته مشکل این است که نتیجه با آنچه زهرا به دنبال آن است مطابقت ندارد: او مقادیر را در سلول های پیوسته می خواهد (بدون خالی) و آنها را به ترتیب صعودی می خواهد.
مسلماً، میتوانید گامهای بیشتری برای به دست آوردن نتایج دلخواه بردارید—به عنوان مثال، میتوانید نتایج را در ستونهای B و C کپی کنید و مقادیر را به عقب بچسبانید (بنابراین فرمولها حذف شوند) و سپس نتایج را مرتب کنید. این مراحل اضافی را به کار شما اضافه می کند.
راهی وجود دارد که با استفاده از یک فرمول آرایه به یک نتیجه بسیار "پاک تر" برسید. فرض کنید مقادیر شما در سلول های A1:A100 هستند. با انتخاب سلول های B1:B100، موارد زیر را در نوار فرمول وارد کنید:
=IFERROR(SMALL(IFERROR(INDEX($A$1:$A$100,SMALL(
IF(MOD($A$1:$A$100,2)=1,ROW($A$1:$A$100)),ROW(
$A1:$A$100))),""),ROW()),"")
به یاد داشته باشید که همه اینها یک فرمول واحد است. از آنجایی که فرمول آرایه ای طراحی شده است، با وارد کردن Ctrl+Shift+Enter آن را خاتمه دهید . نتیجه این است که شما مقادیر فرد را در ستون B، در سلول های پیوسته، به ترتیب صعودی دارید. برای دریافت مقادیر زوج در ستون C، ابتدا B1:B100 را در C1:C100 کپی کنید. سپس محدوده C1:C100 را انتخاب کنید. F2 را فشار دهید تا وارد حالت ویرایش شوید و "=1" را در وسط فرمول به "=0" تغییر دهید. مجدداً با فشار دادن Ctrl+Shift+Enter فرمول را خاتمه دهید .
باید توجه داشته باشید که اگر در محدوده A1:A100 خالی وجود داشته باشد یا مقادیر متنی در محدوده وجود داشته باشد، این فرمول به درستی کار نخواهد کرد. دلیل اینکه جاهای خالی کار نمی کنند این است که از نظر فرمول به عنوان 0 در نظر گرفته می شوند و 0 زوج در نظر گرفته می شوند، بنابراین در ستون C نشان داده می شود. یک فرمول جایگزین برای تعیین مقادیر فرد (ستون B) استفاده از فرمول آرایه زیر در سلول است. B1:
=IFERROR(SMALL(IF(MOD($A$1:$A$100,2)>0,$A$1:
$A$100,"x"),ROW()),"")
برای مقابله با مشکل بالقوه "سلول خالی"، می توانید از فرمول آرایه زیر در سلول C1 استفاده کنید:
=IFERROR(SMALL(IF((MOD($A$1:$A$100,2)=0)*NOT(
ISBLANK($A$1:$A$100)),$A$1:$A$100,"x"),ROW()),"")
B1:C1 را به تعداد سلول های لازم برای دریافت نتایج خود کپی کنید.
قبلاً اشاره کردم که ممکن است استفاده از ماکرو برای پردازش مقادیر خود مفیدتر باشد. دلیل آن ساده است—شما به راحتی می توانید از شر مقادیر تکراری خلاص شوید (در صورت نیاز) و می توانید مقادیر خالی و متن را نادیده بگیرید. راه های مختلفی وجود دارد که می توان چنین کلان را توسعه داد. من روشی را انتخاب کردم که از شما میخواهد سلولهایی را که میخواهید پردازش کنید انتخاب کنید، دو ستون سمت راست آن سلولها را پاک کنید و سپس شانس و زوج را در آن ستونها قرار دهید.
Sub OddsEvens()
Dim rSource As Range
Dim c As Range
Dim sTemp As String
Dim iVal As Integer
Dim bGo As Boolean
Dim sCols As String
Dim vMsg As Variant
Dim lOddCol As Long
Dim iOddPtr As Integer
Dim lEvenCol As Long
Dim iEvenPtr As Integer
Dim iOdds(999) As Integer
Dim iEvens(999) As Integer
Dim J As Integer
Set rSource = Selection
If rSource.Columns.Count = 1 Then
lOddCol = rSource.Column + 1
lEvenCol = rSource.Column + 2
sCols = Chr(lOddCol + 64) & ":"
sCols = sCols & Chr(lEvenCol + 64)
sTemp = "The contents of columns " & sCols
sTemp = sTemp & " will be deleted. Ok to proceed?"
vMsg = MsgBox(sTemp, vbYesNo, "Odds and Evens")
If vMsg = vbYes Then
Application.ScreenUpdating = False
Range(sCols).Clear
iOddPtr = 0
iEvenPtr = 0
For Each c In rSource
bGo = True
Is the cell empty?
If IsEmpty(c.Value) Then bGo = False
Does the cell contain non-numeric value?
If Not IsNumeric(c.Value) Then bGo = False
If bGo Then
iVal = c.Value
If Int(iVal / 2) * 2 = iVal Then
Even number
Check to see if duplicate
For J = 1 To iEvenPtr
If iEvens(J) = iVal Then bGo = False
Next J
If bGo Then
iEvenPtr = iEvenPtr + 1
iEvens(iEvenPtr) = iVal
End If
Else
Odd number
Check to see if duplicate
For J = 1 To iOddPtr
If iOdds(J) = iVal Then bGo = False
Next J
If bGo Then
iOddPtr = iOddPtr + 1
iOdds(iOddPtr) = iVal
End If
End If
End If
Next c
Stuff values into proper columns
For J = 1 To iOddPtr
Cells(rSource.Row + J - 1, lOddCol) = iOdds(J)
Next J
For J = 1 To iEvenPtr
Cells(rSource.Row + J - 1, lEvenCol) = iEvens(J)
Next J
Sort values in Odd column
sTemp = Chr(lOddCol + 64) & rSource.Row & ":"
sTemp = sTemp & Chr(lOddCol + 64) & rSource.Row _
+ iOddPtr - 1
Range(sTemp).Select
Selection.Sort key1:=Range(Chr(lOddCol + 64) _
& rSource.Row), Order1:=xlAscending
Sort values in Even column
sTemp = Chr(lEvenCol + 64) & rSource.Row & ":"
sTemp = sTemp & Chr(lEvenCol + 64) & rSource.Row _
+ iEvenPtr - 1
Range(sTemp).Select
Selection.Sort key1:=Range(Chr(lEvenCol + 64) _
& rSource.Row), Order1:=xlAscending
rSource.Select
Application.ScreenUpdating = True
End If
End If
End Sub
ماکرو کار خود را با پر کردن مقادیر از سلول های انتخاب شده در یکی از دو آرایه (iEvens و iOdds) انجام می دهد. این کار به این دلیل انجام می شود که ماکرو بتواند به راحتی مقادیر تکراری را بررسی کند. فقط اگر سلول خالی نباشد، حاوی یک عدد است و آن عدد تکراری نیست، مقدار به آرایه مناسب اضافه می شود. سپس مقادیر دوباره در دو ستون قرار می گیرند و آن مقادیر مرتب می شوند.