Контекст: у меня есть лист с именем «ForUser» с первой строкой, определяющей заголовки, следующей строкой, соответствующей данным. У меня есть второй лист «ForBuffer» для извлечения данных из базы данных.
Каждый столбец в «ForUser» связан с форматом, который применяется динамически (формат может быть установлен пользователем и изменен). В приведенном ниже примере есть заголовок столбца со значением «Att $» на листе «ForUser», формат которого - доллар.
Dim objRs As ADODB.Recordset
Dim rngDataBuffer As Range
With Application.Workbooks(ThisWorkbook.Name()).Sheets("ForBuffer")
Set rngDataBuffer = .Range("A1")
End With
rngDataBuffer.CopyFromRecordset Data:=objRs
Данные загружаются столбец за столбцом из базы данных и копируются в диапазон с использованием CopyFromRecordset с параметром данных, установленным в действительное значение ADODB.Recordset , на лист с именем «ForBuffer»
Dim rDest As Range
With Application.Workbooks(ThisWorkbook.Name()).Sheets("ForBuffer")
With .Range("A1").CurrentRegion
set rDest= .rows(1).Find( _
What:="Att $", MatchCase:=True, LookIn:=xlFormulas, lookAt:=xlWhole)
End With
End With
Этот буфер затем копируется на лист «ForUser» в столбце, где определен заголовок «Att $». У некоторых ячеек установлено значение, а у некоторых нет.
rngDataBuffer.Copy Destination:=rDest
Я мог бы скопировать данные, хранящиеся в objRs непосредственно в rDest (но это не главное), используя что-то вроде
rDest.Offset(1).CopyFromRecordset Data:=objRs
Смещение (1) необходимо для сохранения первой строки, где есть заголовок «Att $».
Данные сохраняются в виде строки на стороне базы данных, следовательно, падение имеет строки в rngDataBuffer
После этого я применяю формат, используя что-то вроде:
rDest.Offset(1).Resize(rDest.rows.count-1).NumberFormat = "#,##0.00 [$USD]"
для других типов, которые я использую (валюта доллара, текст, процент, число с плавающей точкой, целое число)
.NumberFormat = "#,##0.00 $"
.NumberFormat = "@"
.NumberFormat = "0.00%"
.NumberFormat = "0.0"
.NumberFormat = "0"
Я могу проверить, что формат установлен, но не отображается, возможно, потому что данные были скопированы как строки.
Как можно преобразовать диапазон ячеек в некоторый тип (здесь я говорю «тип», потому что «формат» выглядит именно так, как он выглядит).
Я пытался Скопировать значение 1 из некоторой ячейки, а затем PasteSpecial с различными параметрами. Я могу получить ожидаемый формат отрисовки, но это имеет недостаток, чтобы установить 0 (ноль) в ячейках, которые не имеют содержимого (ноль или пусто). Нулевое значение ячейки или пустая ячейка имеют другое значение в контексте моего приложения. Также это решение не работает для отображения дат.
Я также пытался конвертировать данные в соответствии с типом. Он все время терпит неудачу с очень явным сообщением: Несоответствие типов (ошибка 13). Значение - это строка, но они могут быть преобразованы в ожидаемый тип. Преобразование применяется к значению диапазона (несколько ячеек)
На дату
.Value = CDate(.Value)
Для числовых "типов" (целое число, число с плавающей запятой и валюта соответственно)
.Value = CLgn(.Value)
.Value = CDbl(.Value)
.Value = CCur(.Value)
Ничего из этого не сработало.
Я придумал что-то, что действительно удивило меня
.Value = .Value
Какого черта, или я должен спросить, что за магия стоит за этим? Между прочим, это работает для даты, валюты и двойного числа, а не для целых чисел и процентов!