2017-02-02 9 views
1

У меня есть отчет, который используется для импорта данных, относящихся к планам работы, а затем создает графики и статистику на основе данных. Расчеты и графики основаны на таблицах, а таблицы заполняются VBA - пользователь выбирает файл, а затем VBA проверяет его соответствие ожидаемому формату файла и помещает все в нужное место.Excel VBA PasteSpecial не вставлять последовательно

HOWEVER, пастообразная часть кода не вставляет все правильно. В частности, существует несколько столбцов с датами и при вставлении некоторых из них (не один столбец или отдельные строки, но, казалось бы, случайные ячейки) не форматируются как даты при вставке и поэтому не фиксируются в формулах, когда я ищу работу в определенные таймфреймы.

В исходном файле все данные сохраняются на 100% как значение даты (если я поместил фильтр на данные, он будет сгруппирован по году и может быть расширен до месяца/дня/времени +, если я использую тест ячейку, чтобы добавить 1 к ячейкам, которые показывают следующую дату). После того, как вы вставили в целевой лист, некоторые из них все еще являются датой, но некоторые из них выглядят как текст и отображаются как dd/mm/yyyy hh: mm, но упускаются из расчета. На этих ячейках, если я нахожу на них, нажмите F2, а затем Enter, затем ячейка изменится на дату (перестраивается вправо, а затем включается в формулы daterange).

Вот код:

Public Sub importdata() 
Dim wb1, wb3 As Workbook 
Dim ws1, ws3 As Worksheet 
Dim lrow As Long 
Dim WOtable As ListObject 
Dim searchcell As Range 

Set wb1 = ThisWorkbook 
Set ws1 = wb1.Sheets("Dashboard") 
Set WOtable = ws1.ListObjects("workorder") 

WOfile = Application.GetOpenFilename(FileFilter:="Excel Files (*.CSV),*.CSV", Title:="Select Workorder Extract To Be Opened",MultiSelect:=False) 
If WOfile = False Then Exit Sub 
Set wb3 = Workbooks.Open(WOfile) 
Set ws3 = wb3.Sheets(1) 

ws3.Range("M:M, O:O, Q:Q").EntireColumn.Delete 
    If ws3.Range("A1").Value = "jobnumber" And ws3.Range("B1").Value ="jobdesc" And etc etc Then 
    lrow = ws3.Range("A1").End(xlDown).Row 
    ws3.Range("A2:O" & lrow).Copy 
    WOtable.DataBodyRange(1, 1).PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False 
    Application.CutCopyMode = False 
    Else: MsgBox ("File selected to import workorder information was not in expected format, please check the file and retry.") 
End If 

wb3.Close False 

End Sub 

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

ws3.Columns("E:K").NumberFormat = "DD/MM/YYYY HH:MM:SS" 

Спасибо за любая справка

+1

Вы можете запустить текст столбцов с параметрами по умолчанию против столбца/с в вопросе, чтобы сделать эквивалент F2/Enter для всей колонки - Это можно сделать программно. – Zerk

+2

Использование копирования и вставки для перемещения данных вокруг книги (книг) очень грязно и подвержено ошибкам при использовании одного буфера обмена (для всей ОС) для перемещения информации вокруг. Например. если у вас несколько запущенных процессов и использование буфера обмена, у вас будет ситуация, когда вы вставляете другие данные процессов в то место, где ожидаете чего-то другого. Вы пытались скопировать информацию в массив, а затем записать этот массив обратно на лист, который вы хотите получить? (Он также сохранит тип, и у вас не будет конкуренции за буфер обмена). – 765tgs

+0

@ 765tgs ah Я вижу, может быть, это вызывает проблему. Я не пытался это сделать и не делал этого раньше, если вы знаете какие-либо хорошие ресурсы, где я могу научиться этому, тогда я был бы очень признателен, если бы вы могли поделиться другим, я попытаюсь найти что-то в google. Спасибо – SMLBW

ответ

2

Как обсуждалось в комментариях, пример использования толкания данных в массив вариантов, а затем вставка его в пункт назначения. Несколько замечаний:

  • Всегда указывайте, какой тип вы хотите для каждой переменной, переменные, разделенные запятыми в одной строке, не все принимают последний тип.
  • Используйте с заявлениями, чтобы код был немного чистым и уменьшал количество ссылок, которые нужно решить.
  • Поскольку вы не очистили содержимое таблицы (просто перезаписали их), я воспроизвел это поведение в коде, поскольку я предполагаю, что он предназначен.

Отредактировано суб:

Public Sub importdata() 
Dim wb1 As Workbook, wb3 As Workbook 
Dim ws1 As Worksheet, ws3 As Worksheet 
Dim WOtable As ListObject 
Dim varTMP As Variant 

Set wb1 = ThisWorkbook 
Set ws1 = wb1.Sheets("Dashboard") 
Set WOtable = ws1.ListObjects("workorder") 

WOfile = Application.GetOpenFilename(FileFilter:="Excel Files (*.CSV),*.CSV", Title:="Select Workorder Extract To Be Opened", MultiSelect:=False) 
If WOfile = False Then Exit Sub 
Set wb3 = Workbooks.Open(WOfile) 
Set ws3 = wb3.Sheets(1) 

With ws3 
    .Range("M:M, O:O, Q:Q").EntireColumn.Delete 
    If .Range("A1").Value = "jobnumber" And .Range("B1").Value ="jobdesc" And etc etc Then 
     'load data into variant array 
     varTMP = .Cells(1, 1).CurrentRegion 
     'If you want to do any data manipulation on the array, do it here 
     'Paste array 
End With 
     With WOtable.DataBodyRange 
      Range(.Cells(1, 1), .Cells(0 + UBound(varTMP, 1), 0 + UBound(varTMP, 2))) = varTMP 
     End With 
    Else 
     MsgBox ("File selected to import workorder information was not in expected format, please check the file and retry.") 
    End If 

wb3.Close False 

End Sub 
+0

большое спасибо за ваш ответ! Пара вопросов. Во-первых, таблица уже пуста, когда я перехожу к загрузке этих данных - это изменяет то, что вы предлагаете, учитывая ваш третий маркер? Во-вторых, мне нужно адаптировать строку (1,1) .CurrentRegion, чтобы правильное количество строк и столбцов было втянуто в массив, или бит currentregion делает некоторые предположения? – SMLBW

+1

1) Стол пустой, это нормально. 2) CurrentRegion (https://msdn.microsoft.com/en-us/library/office/ff196678.aspx) выберет весь набор данных, если между ним нет пустых строк или столбцов (хорошо управляемые данные shouldn ' у них есть). Если они присутствуют и нет способа удалить их, укажите свой диапазон, используя стандартные подходы. – Zerk

+0

спасибо. могут быть пустые строки и столбцы (данные, которые вытаскиваются, могут не быть должным образом уточнены другими пользователями при экспорте данных из отдельного программного обеспечения плана работы). вы считаете, что строка varTMP = .Cells (2, 1) .offset (15, lrow-1) будет работать, если будет 15 столбцов (это исправлено), и я вставляю строку lrow = ws3.Range («A1») .End (xlDown). Досрочно? вернется на мой компьютер и сможет протестировать завтра. спасибо – SMLBW