#excel #vba
#excel #vba
Вопрос:
Возможно ли каким-либо образом перенести часть массива vba в диапазон Excel?
Мне нужно сделать что-то вроде этого:
dim testday() as Variant
testday = Sheets("raw").Range("E745:BN745").Value
Sheets("raw").Range("E745:BN745").Value = ""
Sheets("Interface").Range("B4:E4") = testday(3, 4, 5, 6).Value
но это не работает … есть ли способ это исправить? Спасибо!
Комментарии:
1. Я предпочитаю
Sheets("raw").Range("E745:BN745").ClearContents
2. Да, я обычно это делаю, но у меня они отформатированы условно, и я хочу сохранить это, но спасибо!
3.
ClearContents
не удаляет условное форматирование.4. хм, хорошо, так что это отличается от .clear? спасибо за это!
Ответ №1:
Вы можете нарезать функцию Array
using Index
Sub Slicer()
Dim testday() As Variant
testday = Sheets("raw").Range("E745:BN745").Value
Sheets("raw").Range("E745:BN745").Value = ""
Sheets("Interface").Range("B4:E4")= Application.Index(testday, 1, Array(3, 4, 5, 6))
End Sub
Комментарии:
1. Это классный подход, и он превосходит мой по простоте ( 1). Вместо
Array(3,4,5)
я бы использовалEvaluate("TRANSPOSE(ROW(" amp; lStartIndex amp; ":" amp; lFinishIndex amp; "))")
, который создает одномерный массив чисел, начинающийся соlStartIndex
всего путиlFinishIndex
, и может использоваться для динамического выделения произвольного длинного (непрерывного) массива.2. Я не понимаю, как вы используете Index. Последним значением должен быть номер столбца, но вместо этого у вас есть массив? Как это работает?
Ответ №2:
Если массив, который вы хотите скопировать, является одномерным, и вам нужно скопировать смежные ячейки, вы можете использовать функцию CopyMemory:
Option Explicit
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Sub test()
Dim vArr(), vArr2()
Dim lCnt As Long
Dim lStartIndex As Long, lFinishIndex As Long, lLength As Long
With Application
vArr = .Transpose(.Transpose(Range("A1:R1").Value2))
End With
lStartIndex = 3
lFinishIndex = 6
lLength = lFinishIndex - lStartIndex 1
ReDim vArr2(1 To lLength)
CopyMemory vArr2(1), vArr(lStartIndex), lLength * 16
For lCnt = LBound(vArr2) To UBound(vArr2)
Debug.Print vArr2(lCnt)
Next lCnt
Range("A2").Resize(1, UBound(vArr2)).Value2 = vArr2
End Sub
Протестировано с первой строкой
67.2 9 57.2 boo 52 64 76 39 48 50 28 54 96 29 98 25 68 19
ВОЗВРАТ
57.2 boo 52 64
во второй строке.
Таким образом, ваш фрагмент изменится следующим образом
dim testday(), testday2()
With Application ' Value2 is faster than Value
testday = .Transpose(.Transpose(Sheets("raw").Range("E745:BN745").Value2))
End With
Sheets("raw").Range("E745:BN745").ClearContents ' Good suggestion by JFC
CopyMemory testday2(1), testday(3), 4 * 16 ' Variant = 16 Bytes
Sheets("Interface").Range("B4:E4").Value2 = testday2 ' I would do Resize instead
Надеюсь, это поможет!
Ответ №3:
Вы можете либо:
-
Используйте цикл, чтобы скопировать нужные вам значения в новый массив и записать их в свой диапазон. Если вы собираетесь делать это часто, вы можете написать повторно используемую функцию, которая делает это. Или,
-
Прочитайте только то, что вам нужно из вашего
"raw"
листа, и запишите это в свой диапазон, как показано ниже. Это, вероятно, самое простое решение в вашем конкретном случае.
Dim testday() As Variant
testday = Sheets("raw").Range("G745:J745").Value ' only read what you need
Sheets("raw").Range("E745:BN745").ClearContents
Sheets("Interface").Range("B4:E4") = testday(3, 4, 5, 6).Value
Комментарии:
1. да, спасибо, но мне нужен тестовый день (7,8,9,10) для C4: E4 и т.д. итак, первый метод был бы лучше