مایک خاطرنشان می کند که هنگام کپی کردن اعداد از یک کاربرگ به کاربرگ دیگر از طریق یک ماکرو، این عدد اغلب به صورت متن ارسال می شود. او فکر می کند که آیا می تواند این مشکل را از طریق کدهای VBA حل کند.
هنگامی که اطلاعات را با استفاده از یک ماکرو کپی می کنید (با استفاده از روش کپی)، تنها زمانی که باید عددی را به عنوان متن "در حال ارسال" به دست آورید، این است که شماره در منبع، به عنوان متن قالب بندی شده باشد. می توانید این اتفاق را در یک ماکرو ساده مانند موارد زیر مشاهده کنید:
Sub TestCopy1()
Dim s As Range
Dim t As Range
Set s = Sheets("Sheet2").Range("D7:D11")
Set t = ActiveSheet.Range("A4")
s.Copy
t.Select
ActiveSheet.Paste
End Sub
هر چیزی که در محدوده منبع (D7:D11) باشد که به عنوان متن قالب بندی شده باشد، به عنوان متن چسبانده می شود. بنابراین، اگر اعدادی را به عنوان متن در منبع قالب بندی کنید، آنها به عنوان متن در هدف قالب بندی می شوند.
راه حل این است که از روش PasteSpecial به جای روش Paste استفاده کنید:
Sub TestCopy2()
Dim s As Range
Dim t As Range
Set s = Sheets("Sheet2").Range("D7:D11")
Set t = ActiveSheet.Range("A4")
s.Copy
t.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Selection.Value = Selection.Value
End Sub
ماکرو همچنان یک منبع و محدوده هدف را تنظیم می کند و سپس از روش .Copy برای کپی منبع استفاده می شود. در مرحله بعد، از روش .PasteSpecial برای چسباندن فقط مقادیر به محدوده هدف استفاده می شود. پس از تکمیل این خط کد، محدوده چسبانده شده به طور خودکار انتخاب می شود. در نهایت، خط آخر اساساً اکسل را وادار می کند تا دوباره آنچه را که در سلول ها چسبانده شده است ارزیابی کند. این مرحله نهایی است که مقادیر متنی را به مقادیر عددی تبدیل می کند.
استفاده از روش .PasteSpecial در این روش یک اشکال دارد - اگر داده های منبع شما حاوی تاریخ یا زمان باشد، آن ها به عنوان مقادیر عددی قرار می گیرند. بنابراین، ممکن است لازم باشد برخی از قالب بندی های اضافی را روی مقادیر هدف خود انجام دهید. این منجر به یک رویکرد کاملاً متفاوت می شود، رویکردی که از .Copy، .Paste یا .PasteSpecial استفاده نمی کند. در این روش شما از یک برنامه فرعی برای عبور از تمام سلول های یک محدوده استفاده می کنید و سپس آنها را در جایی که می خواهید کپی می کنید:
Sub TestCopy3()
Dim s As Range
Dim t As Range
Set s = Sheets("Sheet2").Range("D7:D11")
Set t = ActiveSheet.Range("A4")
DoCopy(s, t)
End Sub
Sub DoCopy(Src As Range, Tgt As Range)
Dim r As Range
Dim c As Range
Dim V As Variant
Dim iRow As Integer
Dim iCol As Integer
If Tgt.Cells.Count = 1 Then
iRow = 0
For Each r In Src.Rows
iCol = 0
For Each c In r.Cells
V = c.Value
If IsNumeric(V) Then
If Not IsDate(V) Then V = V * 1
End If
Tgt.Offset(iRow, iCol).NumberFormat = "General"
Tgt.Offset(iRow, iCol).Value = V
iCol = iCol + 1
Next c
iRow = iRow + 1
Next r
Else
MsgBox "Target must be a single cell"
End If
End Sub
دو ماکرو در این کد وجود دارد که اولی (TestCopy3) برای راه اندازی و فراخوانی دومی (DoCopy) استفاده می شود. ماکرو TestCopy3 بسیار شبیه ماکروهایی است که قبلاً در این نکته استفاده شده بود. این زیرروال DoCopy است که کارهای سنگین را برای ما انجام می دهد. این مستلزم آن است که یک محدوده منبع (Src) و یک محدوده هدف (Tgt) به آن ارسال شود. محدوده هدف یک سلول واحد است که نشان دهنده جایی است که می خواهید کپی قرار گیرد.
ماکرو از هر سلول از هر ردیف در محدوده منبع عبور می کند و بررسی می کند که آیا عددی است یا خیر. اگر چنین باشد، و تاریخ نباشد، آنگاه مقدار در 1 ضرب می شود. در نهایت، مقدار در سلول آفست درست از محدوده هدف مشخص شده قرار می گیرد.
همچنین توجه داشته باشید که ماکرو فرمت سلول هدف را روی General تنظیم می کند. این کار فقط در صورتی انجام می شود که سلول هدف در ابتدا به صورت متن فرمت شده باشد. اگر مطمئن هستید که اینطور نیست (یا اگر نمی خواهید تمام سلول های کپی شده به عنوان عمومی فرمت شوند)، می توانید نظر بدهید یا این خط کد را حذف کنید.