У меня возникли проблемы со следующим кодом. Всякий раз, когда я запускаю код vba, код CleanFileName и CleanUsedRange удаляют мои формулы Vlook.

Есть ли способ использовать CleanFileName и CleanUsedRange без удаления формул Vlook. коды ниже

 Private Sub CommandButton1_Click()
Const FULL_PATH = "C:\Documents\test\quot.txt"
Dim fId As String, txt As String, txtLen As Long, d As Object, dc As Long

fId = FreeFile
Open FULL_PATH For Input As fId
    txt = Input(LOF(fId), fId)  'Read entire file (not line-by-line)
Close fId
txtLen = Len(txt)
Set d = CreateObject("Scripting.Dictionary")
d("Name") = "C11"   'Same as: d.Add Key:="Name", Item:="C11"
d("Phone") = "H13"
d("Address1") = "C15"
d("Email") = "C13"
d("Postcode") = "H16"
d("SR") = "C10"
d("MTM") = "H14"
d("Serial") = "H15"
d("Problem") = "C17"
d("Action") = "C18"
d("Dated") = "H10"
dc = d.Count

Dim i As Long, k As String, sz As Long, found As Long
With ThisWorkbook.Worksheets("Sheet1")     '<--- Update sheet name
    For i = 0 To dc - 1     'd.Keys()(i) is a 0-based array
        k = d.Keys()(i)     'Name, Phone, etc
        found = InStr(txt, k) + Len(k) + 1  'Find the (first) key in file
        If found > 0 Then   'Determine item length by finding the next key
            If i < dc - 1 Then sz = InStr(txt, d.Keys()(i + 1)) Else sz = txtLen + 2
            .Range(d(k)).Value2 = Trim$(Mid$(txt, found, sz - found - 1))
        End If
    Next
End With
End Sub

Чистый файл

Public Function CleanFileName(ByVal fName As String) As String
Dim b() As Byte, specialChars As Variant, i As Long

b = "\/:*?|<>" & Chr(34) & Chr(8) & Chr(9) & Chr(10) & Chr(13)

specialChars = Split(StrConv(b, vbUnicode), Chr(0))

fName = Trim$(fName)    'Trim, then remove \ / : * ? | < > " Backspace Tab LF CR
For i = 0 To UBound(specialChars)
    fName = Replace(fName, specialChars(i), vbNullString)
Next
CleanFileName = fName
End Function

Второй код

 Public Sub CleanUsedRange(ByRef ur As Range)
Dim arr As Variant, r As Long, c As Long

arr = ur.Formula
For r = 1 To UBound(arr, 1)
    For c = 1 To UBound(arr, 2)
        arr(r, c) = CleanFileName(arr(r, c))
    Next
Next
ur.Formula = arr
End Sub

Код экспорта

Private Sub CommandButton2_Click()
Dim ws As Worksheet, fPath As String, fName As String, dt As String

Set ws = ThisWorkbook.Worksheets("Sheet1")

fPath = "C:\Documents\test\"
dt = Format(Date, " - MM-DD-YYYY")

CleanUsedRange ws.UsedRange

fName = fPath & ws.Range("C10") & dt & " - Quotation"

ws.Range("A1:I60").ExportAsFixedFormat Type:=xlTypePDF, FileName:=fName
End Sub

Формулы Vlook используются для импорта данных с другого листа, поэтому вам не нужно вводить их один за другим. Есть ли способ выкрутить чистый файл, чтобы не удалять формулы vlook.


После редактирования кода, как вы предложили

Private Sub CommandButton2_Click()
Dim ws As Worksheet, fPath As String, fName As String, dt As String

Set ws = ThisWorkbook.Worksheets("Sheet1")

fPath = "C:\Users\Documents\test\\"
dt = Format(Date, " - MM-DD-YYYY")

Range("C10") = CleanFileName(Range("C10"))


fName = fPath & ws.Range("C10") & dt & " - Quotation"

ws.Range("A1:I60").ExportAsFixedFormat Type:=xlTypePDF, FileName:=fName
End Sub

Тем не менее, экспортированный файл, похоже, имеет иностранные символы .. как показано ниже

Изображение1

Image2

Любое другое решение?

Я изменил код, как вы предложили, но я не могу запустить VBA. После добавления этого:

 .Range(d(k)).Value2 = Trim$(Mid$(txt, found, sz - found - 2))

Это где ошибка указывает

Open FULL_PATH For Input As fId

Смотрите картинку новая ошибка

Также найдите требуемый шестнадцатеричный код

Шестнадцатеричная картинка

Я изменил код на

 Else sz = txtLen + 3

Тем не менее, я все еще получаю сообщение об ошибке 76 Ошибка 76 И отладка указывает на эту строку;

 Open FULL_PATH For Input As fId

1 ответ1

0

Я не думаю, что ваши CleanUsedRange() и CleanFileName() на самом деле (полностью) удаляют ваши формулы Vlook (какими бы они ни были), но ваши формулы могут быть уничтожены CleanFileName() при удалении определенных символов.


Чтобы объяснить, почему ваш текущий код создает проблемы, давайте проанализируем несколько строк:

В CommandButton2_Click() вы вызываете CleanUsedRange ws.UsedRange . Здесь ws относится к "Sheet1" а UsedRange представляет используемый диапазон ws , то есть диапазон ячеек между первым и последним столбцами (включительно) и первой и последней строками (включительно), которые имеют (или имели) содержимое (например, данные или формулы).

В CleanUsedRange() вы пересекаете все ячейки (каждую строку и столбец) используемого диапазона (передается как ur As Range) и вызываете CleanFileName() для содержимого всех этих ячеек. Эта функция (CleanUsedRange()) является основной причиной разрушения ваших формул, потому что она передает формулы в вашем рабочем листе в виде строк в CleanFileName() .

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


Исправлено: не передавайте весь использованный диапазон в CleanUsedRange() и CleanFileName() . На самом деле вы можете полностью отказаться от CleanUsedRange() .

Пройдите только одну клетку (C10?) который содержит имя файла, который может нуждаться в очистке, для CleanFileName() .

IOW, в CommandButton2_Click() заменить

CleanUsedRange ws.UsedRange

с

Range("C10") = CleanFileName(Range("C10")).

(Предполагая, что ячейка C10 содержит имя файла для использования.)


Редактировать в отношении "вопросительные знаки в штучной упаковке"

Для проблемы с "в штучной упаковке вопросительные знаки" я обнаружил, что любой символ с кодом меньше 32 создает проблему в .pdf файле, созданном в Excel (в моем Excel только Chr (12) отображается как "в штучной упаковке вопросительный знак"). «). Ясно, что между каждым полем есть два таких символа, и вероятными являются пара «Возврат каретки - Перевод строки» (CRLF), но только вы можете подтвердить это, поскольку вы еще не предоставили эту информацию.

Когда вы читаете значения из строки txt вы используете этот код:

.Range(d(k)).Value2 = Trim$(Mid$(txt, found, sz - found - 1))

Меняя его на

.Range(d(k)).Value2 = Trim$(Mid$(txt, found, sz - found - 2))

как я предположил в комментарии, излечивает проблему.


Редактировать относительно ошибки 7.8.2018

Во-первых, спасибо за файл. Это ясно подтверждает мое подозрение о паре CRLF между полями в файле. Это также подтверждает, что длина данных, которые мы извлекаем с помощью функции Mid$() должна быть уменьшена на 2 вместо 1.

Мне не удалось воспроизвести ошибку, с которой вы столкнулись в предыдущей модификации, но действительно есть еще одна ошибка с последним полем ("Дата"). Возможно, это вызвано ошибкой в вашей среде, это не в моей, но год ошибочно показан как 201.

Ошибка с последним полем состоит в том, что переменная sz должна расти, чтобы компенсировать предыдущее изменение, которое мы сделали при извлечении данных (мы изменили sz - found - 1 на sz - found - 2).

Итак, измени

Else sz = txtLen + 2

в

Else sz = txtLen + 3

Конечно, это помогает, только если ошибка возникает при чтении последнего поля ("Дата") файла. Если это не помогло, пожалуйста, отладьте и дайте мне знать, какое поле вы читаете, и какие значения имеют переменные k , found и sz , когда он терпит неудачу. Также сообщите о любых всплывающих сообщениях, которые могут отображаться.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .