Как создать макрос, который может применить формулу к динамическому диапазону ячеек, предпочтительно используя массив? - PullRequest
0 голосов
/ 04 июня 2019

Я совершенно новичок в VBA, так что эта задача для меня немного сложна, но держу пари, что это легко для вас, ребята.Я пытаюсь создать макрокоманду, которая может автоматически преобразовывать серию дат из текста в формат даты, который Excel может распознать.Это задача, которую я регулярно выполняю, поэтому было бы очень экономно, если бы макрос выполнял ее для меня.По сути, я регулярно скачиваю временные ряды, например, историческую цену акции.Длина временного ряда меняется каждый раз.Затем мне нужно будет преобразовать даты из загруженных данных в формат, который распознает Excel.

Для этого я использую следующий код:

=DATE(RIGHT(B2,4),MONTH("1 "&MID(B2,4,3)),LEFT(B2,2))

вячейка рядом с первой строкой ряда дат.Затем я автоматически заполняю эту формулу до конца ряда.

Я создал макрос, который выполняет эту задачу для меня, используя следующий код:

Sub FacsetDates()
' FacsetDates Macro
' Turn Factset dates into excel format
'
' Keyboard Shortcut: Ctrl+Shift+D

   ActiveCell.FormulaR1C1 = _
        "=+DATE(RIGHT(RC[-1],4),MONTH(""1 ""&MID(RC[-1],4,3)),LEFT(RC[-1],2))"
    Selection.End(xlToLeft).Select
    Dim Lastrow As Long
    Lastrow = Cells(Rows.Count - 1, ActiveCell.Column).End(xlUp).Row
    Selection.End(xlToRight).Select
    Selection.AutoFill Destination:=ActiveCell.Range("A1:A" & Lastrow - 1)
    ActiveCell.Range("A1:A" & Lastrow - 1).Select
End Sub

Моя проблема заключается в том, что этот код работает, только если ряд дат начинается со строки 2. Еслиесли серия вставлена ​​из строки 1, автоматическое заполнение прервет одну строку, а если серия начинается с строки 3, автоматическое заполнение заполнит одну строку слишком сильно (по сравнению с длиной ряда данных)

Мне нужен макрос, который работает независимо от того, с какой строки начинается ряд данных.Например, я хотел бы, чтобы макрос работал, даже если ряд дат начинается в B10.Я полагаю, что решение состоит в том, чтобы установить ряд данных в виде массива в VBA, а затем выполнить цикл, который манипулирует каждой строкой текста, а затем, наконец, вставить данные в соседний столбец.Я начал создавать следующий код:

Sub FSdate()

 Dim arrMarks() As Long
 Lastrow = Cells(Rows.Count, ActiveCell.Column).End(xlUp).Row
 ReDim arrMarks(1 To Lastrow)

Dim i As Long
 For i = LBound(arrMarks) To UBound(arrMarks)
    arrMarks(i) = ActiveCell
 Next i

, в котором я пытаюсь сначала определить массив и его размер, а затем «скопировать» строку текста из активной ячейки (являющейся первой строкойряд данных), но этот код не работает.Определив массив, я подумал о том, чтобы запустить цикл, использующий функцию DATE сверху, чтобы управлять каждой отдельной записью в массиве.Но мои текущие навыки в VBA здесь не оправдываются, и я просто не знаю, как поступить.

Может кто-нибудь помочь создать такой код?или даже, есть ли у вас, ребята, вклад в альтернативные способы выполнения этой задачи?Вероятно, исходный код можно манипулировать для работы независимо от того, с какой строки начинается ряд данных.

Надеюсь, кто-нибудь сможет и захочет мне помочь!

Ответы [ 2 ]

1 голос
/ 04 июня 2019

Это упрощенная разбивка ответа @Dave, поскольку вы хотите использовать ячейку, с которой вы выбираете начать. Первый; установите последнюю строку, считая строки в столбце слева от активной ячейки. Во-вторых, установите диапазон от активной ячейки до переменной последней строки. Третье: напишите свою формулу в ассортимент. Примечание: lRow - ActiveCell.Row + 1 регулирует ваш диапазон на основе номера строки активной ячейки.

Dim lRow As Long
lRow = Cells(Rows.Count, ActiveCell.Offset(, -1).Column).End(xlUp).Row

ActiveCell.Resize(lRow - ActiveCell.Row + 1).FormulaR1C1 = "=+DATE(RIGHT(RC[-1],4),MONTH(""1 ""&MID(RC[-1],4,3)),LEFT(RC[-1],2))"

более простой способ выполнить вашу задачу; при перезаписи текущего текста будет использоваться TextToColumns

ActiveSheet.Columns("F").TextToColumns Destination:=ActiveSheet.Columns("F"), DataType:=xlDelimited, _
    TextQualifier:=xlDoubleQuote, FieldInfo:=Array(1, 3), TrailingMinusNumbers:=True
    Columns("F").NumberFormat = "m/d/yyyy"
0 голосов
/ 04 июня 2019

Если мы сначала посмотрим, что происходит:

Sub FacsetDates()
' FacsetDates Macro
' Turn Factset dates into excel format
'
' Keyboard Shortcut: Ctrl+Shift+D

    ' Enter Formula in the current cell
   ActiveCell.FormulaR1C1 = _
        "=+DATE(RIGHT(RC[-1],4),MONTH(""1 ""&MID(RC[-1],4,3)),LEFT(RC[-1],2))"
    ' Move to the leftmost cell in a contiguous range from the current cell
    Selection.End(xlToLeft).Select
    Dim Lastrow As Long
    ' Get the row number of the bottom cell in the same column as the now selected cell
    Lastrow = Cells(Rows.Count - 1, ActiveCell.Column).End(xlUp).Row
    ' Move to the rightmost cell in a contiguous range from the now selected cell
    Selection.End(xlToRight).Select
    ' Fill down from the current cell by the same number of cells in the range from A1 to the last row
    Selection.AutoFill Destination:=ActiveCell.Range("A1:A" & Lastrow - 1)
    ActiveCell.Range("A1:A" & Lastrow - 1).Select
End Sub

В чем проблема с диапазоном, так это то, что ActiveCell.Range ("A1: A" & Lastrow - 1) не ссылается на строки 1х на листе, это относится к строкам от 1 до х в вашем диапазоне , который начинается со строки 2 или 3 и т. д.

Вы также очень быстро поймете, что изменение выбора в кодетребует много времени / ресурсов и подвержен ошибкам, возникающим, например, если выбор изменяется во время выполнения вашего кода.

Я бы рассмотрел жесткое кодирование столбца, в котором вы выводите формулу, если она всегда будет одинаковой дляи чтобы не делать выбор.Вы можете сделать это и ввести формулу непосредственно в столбец C следующим образом:

Sub FacsetDates2()

    Dim Lastrow As Long
    ' Get the row number of the bottom cell in column A
    Lastrow = Cells(Rows.Count - 1, 1).End(xlUp).Row
    Range("C2:C" & Lastrow).FormulaR1C1 = "=+DATE(RIGHT(RC[-1],4),MONTH(""1 ""&MID(RC[-1],4,3)),LEFT(RC[-1],2))"

End Sub

EDIT -

Используя активную ячейку и переходя к концу диапазона, как определено в столбце A, выможет использовать это:

Sub FacsetDates2()

    Dim Lastrow As Long
    Dim c As Range
    Dim currentRow As Long
    Dim currentColumn As String

    ' Store a reference to the active cell
    Set c = ActiveCell
    ' Get the row number and column name of the active cell
    currentRow = c.Row
    currentColumn = Replace(c.Address, currentRow, "")

    ' Get the row number of the bottom cell in column A
    Lastrow = Cells(Rows.Count - 1, 1).End(xlUp).Row
    Range(c.Address & ":" & currentColumn & Lastrow).FormulaR1C1 = "=+DATE(RIGHT(RC[-1],4),MONTH(""1 ""&MID(RC[-1],4,3)),LEFT(RC[-1],2))"

End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...