2016-11-01 5 views
1

Я хочу создать сводную таблицу на новом листе, и на данный момент я просто делаю это очень грубо. Я попробую более элегантное решение в будущем.cells(). Value = ... ошибка приложения или объекта

Во всяком случае, это код, который я до сих пор:

Sub createsummarytable() 

Worksheets.Add().Name = "datasummary" 

With Worksheets("datasummary") 

Dim i As Long 
Dim Startpoint As Long 

Startpoint = -5 

For i = 1 To 40 
.Cells(Startpoint + (5 * i), 1).Value = "Block" & "i" 
Next i 

End With 
End Sub 

Я получаю ошибку в названии на линии: .Cells(Startpoint + (5 * i), 1).Value = "Block" & "i"

Если кто-то хочет, чтобы сделать код более элегантным в дополнение к решение этой ошибки было бы оценено.

ответ

2

Пробег-по-одном. В Excel нет столбца/строки 0; -5 + (5 * 1) принимает значение 0:

.Cells(0, 1).Value = 42 'same error 

Вам нужно отрегулировать +1:

For i = 1 To 40 
    .Cells(Startpoint + (5 * i) + 1, 1).Value = "Block" & i 
Next i 

Если ваш код работает, как задумано, описать свой рабочий код в новый вопрос о Code Review.

+2

Ответ Матта Мага должен решить вашу ошибку. Возможно, стоит также упомянуть, что если вы намерены использовать свой счетчик i, чтобы ваш вывод был Block 1, Block 2, Block 3 и т. Д., Тогда вам нужно будет изменить свой код на: '.Cells (Startpoint + (5 * i) +1,1) .Value = «Block» & i', иначе вы будете многократно получать Blocki, Blocki, Blocki – kpg987

+0

Argh какая ужасающая глупая ошибка! Спасибо, Мат-Маг, это работает. Почему вы хотите, чтобы я описал свой код в Code Review SE? Спасибо @ kpg987 за этот улов. Я бы сам нашел эту ошибку, если бы мой код повторился так далеко. – shecodes

0

@ кружкой Мэта взял на вне по-одному ошибки, и @ kpg987 получил ваше использование "i" в виде строки-литерала вместо переменной, но ваш код может быть улучшен.

Вот некоторые из изменений, которые я сделал:

  • Scope процедура для частных или общественных

  • Используйте осмысленные имена

  • Используйте константы, чтобы определить начальную строку и количество каждая строка для каждого блока. StartingPoint = -5 не полезен, тогда как START_ROW = 1 совершенно ясно, что это такое и где он начнется.

  • Отрегулируйте формулу для использования констант.

  • Непосредственно обратитесь к целевой книге, иначе будет использоваться активная книга.

  • Установите ссылку на добавленный лист при использовании команды add.

  • Используйте строго типизированных ссылку с командой With, потому что With Worksheets("datasummary") будет поздно связанно)

  • Используйте camelCasing для имен переменных

Результат:

Private Sub createSummaryTable() 

    Const WORKSHEET_NAME As String = "datasummary" 
    Const START_ROW As Long = 1 
    Const BLOCK_COLUMN as Long = 1 
    Const BLOCK_SIZE As Long = 5 
    Const BLOCK_COUNT As Long = 40 
    Const BLOCK_PREFIX As String = "Block" 

    Dim dataSummary As Worksheet 
    Set dataSummary = ThisWorkbook.Worksheets.Add 
    With dataSummary 
     .Name = WORKSHEET_NAME 
     Dim blockCounter As Long 
     For blockCounter = 1 To BLOCK_COUNT 
      .Cells(START_ROW + (BLOCK_SIZE * (blockCounter - 1)), BLOCK_COLUMN).Value = BLOCK_PREFIX & blockCounter 
     Next blockCounter 
    End With 
End Sub 
+0

whaat является причиной того, что область охвата является частной или общедоступной? Целью макроса является составление таблицы для суммирования данных из [http://stackoverflow.com/questions/40147555/using-a-dictionary-and-array-to-count-cell-values]. Таким образом, «Блок» относится к определенному набору данных, который в конечном итоге мне нужно будет расширить в текущем макросе с «пробными», «записями AOI» и «RT». Кроме того, что означает camelcasing? – shecodes

+0

'Публичные' процедуры могут вызываться * любым * другим проектом и из любого модуля внутри * самого * проекта. 'Частные' процедуры могут быть вызваны только кодом в * том же модуле в том же проекте *. Лучше всего сделать все 'Private' *, если только это не нужно *. Если вы не укажете 'Public' или' Private', VBE неявно по умолчанию обрабатывает обращение к 'Public', что является * противоположным * того, что вы хотите. Если вам нужна процедура, доступная для всех модулей * внутри * вашего проекта, вы отмечаете процедуру как «Публикация», но отмечаете модуль как «Частный модуль Option». – ThunderFrame

0

подход «без петли»:

Private Sub createSummaryTable2() 
    Dim dataSummary As Worksheet 
    With ThisWorkbook.Worksheets.Add 
     .Name = "datasummary" 
     With .Range("A1").Resize((40 - 1) * 5 + 1) 
      .FormulaR1C1 = "=IF(MOD(ROW(),5)=1,""Block"" & int(ROW()/5)+1,"""")" 
      .Value = .Value 
     End With 
    End With 
End Sub 
Смежные вопросы