VBA Открыть PDF-файлы в списке, выбрав ячейки - PullRequest
0 голосов
/ 05 февраля 2020

Я работаю над листом, который позволит пользователям открывать PDF-файлы на основе частичных имен файлов в разных папках, просто нажимая на ячейку.

Мой вопрос состоит из двух частей.

  1. Я хочу, чтобы путь к файлу "fp" захватывал значение активной ячейки в верхней части выбранного столбца. Я хочу сделать это для удобства использования в будущем, если пути меняются.
  2. Я искал несколько способов открыть PDF из Excel. Кажется, ничего из этого не работает, и я не уверен, почему это так.
Option Explicit

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    'Activate Macro by click a cell
    If Selection.Count = 1 Then
        If Not Intersect(Target, Range("A3:B10000")) Is Nothing Then
            Call OpenFile
        End If
    End If
End Sub

Function OpenAnyFile(strPath As String)
    'Put this in as "ActiveWorkbook.FollowHyperlink OpenMe" was not working. Was trying the shell method.
    Set objShell = CreateObject("Shell.Application")
    objShell.Open (strPath)
End Function

Sub OpenFile()
    Dim fp As String, fn As String, TheFile As String

    fp = "R:\Procurement\Invoices\"
    '(((Item 1))) I want it so that fp will return the top value from the top row of this sheet as i would like the path information to be there for easy user modification.
    fn = ActiveCell.Value

    TheFile = Dir(fp & fn & "*.pdf")

    If CBool(Len(fn)) Then
       MsgBox ("File Found")

       '(((Item 2))) Opening the PDf does not work. Below are two ways i have tried to achieve this.
       Call OpenAnyFile(TheFile)
       'ActiveWorkbook.FollowHyperlink TheFile
    End If
End Sub

Ответы [ 3 ]

0 голосов
/ 05 февраля 2020

Вы можете сделать это:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim rng As Range
    If Target.Count = 1 Then
        Set rng = Application.Intersect(Target, Me.Range("A3:B10000"))
        If Not rng Is Nothing Then
            'Pass the cell value and the value from the top row
            '  of the selected column
            OpenFile rng.Value, Me.Cells(1, rng.Column).Value
        End If
    End If
End Sub


Sub OpenFile(fn As String, fp As String)
    'etc
0 голосов
/ 06 февраля 2020

Мой коллега помог мне с этим. Спасибо за помощь! Ответ ниже. Дайте мне знать, если увидите что-нибудь, что можно улучшить.

Option Explicit

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Selection.Count = 1 Then
        If Not Intersect(Target, Range("A3:B10000")) Is Nothing Then
            Call OpenFile
        End If
    End If
End Sub

Sub OpenFile()

Dim filepath As String
Dim filename As Variant

'So that the macro wont try to open nothing
If ActiveCell.Value = "" Then
    Exit Sub
    End If

'Filepath is at the top of the worksheet above each active cell
filepath = Cells(1, ActiveCell.Column).Value

'File name is just the first portion of the file. the "*" will determine the remaining file name
filename = Dir(filepath & ActiveCell.Value & "*")

'This will open the file below. Needs the filepath and the filenname together although the filepath is inbedded in the filename
If CBool(Len(filename)) Then
    ActiveWorkbook.FollowHyperlink (filepath & filename)

End If

End Sub
0 голосов
/ 05 февраля 2020
  • Способ использования пробелов очень запутан и затрудняет понимание вашей программы.
  • Ваш код не будет компилироваться, как написано.
  • Зачем использовать Function вместо Sub, если вы не возвращаете значение?
  • Вы получите ошибку переполнения, если пользователь нажмет Ctrl A, чтобы выбрать весь лист.
  • Информация о функции оболочки https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/shell-function

При использовании Target.Count могут возникнуть ошибки переполнения. Обычно это происходит с помощью Ctrl + A. Поведение при расширении, если Ctrl + A обеспечивает очень слабую защиту. В лучшем случае вы должны нажать ее три раза, чтобы сначала выбрать регион, затем используемый диапазон, а затем весь лист. В худшем случае требуется один раз.

Из MS Docs re: Range object & Count против CountLarge свойства

https://docs.microsoft.com/en-us/office/vba/api/excel.range.count

Свойство CountLarge функционально аналогично свойству Count, за исключением того, что свойство Count будет генерировать ошибку переполнения, если указанный диапазон имеет более 2 147 483 647 ячеек (один из которых меньше 2048 столбцов). Однако свойство CountLarge может обрабатывать диапазоны вплоть до максимального размера рабочего листа, который составляет 17 179 869 184 ячеек.


Функция оболочки против объекта оболочки

Функция оболочки - это Очень прост в использовании, нет необходимости в дополнительных затратах на создание объекта.

Например, использование функции оболочки для открытия страницы 4 файла myfile.pdf в Inte rnet Explorer:

Shell("C:\Program Files\Internet Explorer\iexplore.exe " + "C:\myfile.pdf#Page=4")

Обратите внимание, что после `" [...] iexplore.exe [...] "есть пробел, который важен.

Замените путь к исполняемому файлу приложением по вашему выбору

Примечание. Многие приложения не могут открыть PDF-файл для указанной c страницы. Просто пропустите часть #Page= в этой проблеме.

Примечание: вы также можете получить PID нового процесса, например:

vPID = Shell("C:\Program Files\Internet Explorer\iexplore.exe " + "C:\myfile.pdf#Page=4")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...