Выбрать дату в календареВыбрать дату в календаре

Страницы: 1 2 След.
WEB API или другие способы подключения к PDF Creator 24
 
Цитата
написал:
насколько я понимаю, в этом решении для моего случая есть несколько проблем:1. Формат размера картинок разный, а Power Point делает их одинаковыми по последней картинке2. Иногда, в конвертации и объединении участвует PDF,
ну вот можно и так, немного с юмором, но вариант рабочий, осуществим анализ на уровне пикселя, мать его:)

Что нужно для склейки (хотя бы одно из):
  1. Adobe Acrobat Pro — дорого, но работает из коробки
  2. PDFtk (бесплатно) — скачать с pdflabs.com, установить, и всё
  3. Ghostscript (бесплатно) — ghostscript.com
  4. Python + PyPDF2 — pip install PyPDF2
Код
Sub ConvertImagesToPDF_UltimateEdition()
    '==========================================================
    ' ULTIMATE PDF CONVERTER v2.0
    ' Теперь с блэкджеком и поддержкой PDF!
    ' Каждая картинка получает СВОЙ размер страницы.
    ' PDF-файлы тоже приглашены на вечеринку.
    '==========================================================
    
    Dim fd As FileDialog
    Dim filesList As New Collection
    Dim i As Long
    Dim outputPath As String
    
    ' ---- Выбор файлов (теперь и PDF!) ----
    Set fd = Application.FileDialog(msoFileDialogFilePicker)
    With fd
        .Title = "Выберите изображения и/или PDF"
        .AllowMultiSelect = True
        .Filters.Clear
        .Filters.Add "Изображения и PDF", "*.jpg;*.jpeg;*.png;*.bmp;*.gif;*.tif;*.tiff;*.pdf"
        .Filters.Add "Только изображения", "*.jpg;*.jpeg;*.png;*.bmp;*.gif;*.tif;*.tiff"
        .Filters.Add "Только PDF", "*.pdf"
        If .Show <> -1 Then Exit Sub
        For i = 1 To .SelectedItems.Count
            filesList.Add .SelectedItems(i)
        Next i
    End With
    
    If filesList.Count = 0 Then
        MsgBox "Вы не выбрали ни одного файла. Грустно.", vbExclamation
        Exit Sub
    End If
    
    ' ---- Настройки ----
    Dim pageSize As String
    pageSize = InputBox("Размер страницы:" & vbCrLf & vbCrLf & _
                        "1 - A4 (210 x 297 мм)" & vbCrLf & _
                        "2 - A3 (297 x 420 мм)" & vbCrLf & _
                        "3 - Letter (216 x 279 мм)" & vbCrLf & _
                        "4 - Подогнать под размер картинки (РЕКОМЕНДУЕТСЯ)" & vbCrLf & _
                        "5 - Квадрат (210 x 210 мм)", _
                        "Настройки PDF", "4")
    If pageSize = "" Then Exit Sub
    
    Dim orientation As String
    If pageSize <> "4" Then
        orientation = InputBox("Ориентация страницы:" & vbCrLf & vbCrLf & _
                               "1 - Книжная (портрет)" & vbCrLf & _
                               "2 - Альбомная (ландшафт)" & vbCrLf & _
                               "3 - Авто (по ориентации картинки)", _
                               "Ориентация", "3")
        If orientation = "" Then Exit Sub
    Else
        orientation = "3"
    End If
    
    ' ---- Путь сохранения ----
    outputPath = Application.GetSaveAsFilename( _
        InitialFileName:="Output.pdf", _
        FileFilter:="PDF (*.pdf), *.pdf", _
        Title:="Сохранить итоговый PDF")
    
    If CStr(outputPath) = "False" Then Exit Sub
    If LCase(Right(outputPath, 4)) <> ".pdf" Then outputPath = outputPath & ".pdf"
    
    ' ---- Подготовка временной папки ----
    Dim tempFolder As String
    tempFolder = Environ("TEMP") & "\VBA_PDF_Merge_" & Format(Now, "yyyymmddhhnnss") & "\"
    MkDir tempFolder
    
    ' ---- Разделяем файлы на картинки и PDF ----
    Dim imageFiles As New Collection
    Dim pdfFiles As New Collection  ' Коллекция: ключ = порядковый номер, значение = путь
    Dim fileOrder() As String       ' Массив для хранения порядка: "IMG" или "PDF"
    Dim fileIndex() As Long         ' Индекс в соответствующей коллекции
    
    ReDim fileOrder(1 To filesList.Count)
    ReDim fileIndex(1 To filesList.Count)
    
    Dim imgCount As Long, pdfCount As Long
    imgCount = 0: pdfCount = 0
    
    For i = 1 To filesList.Count
        Dim ext As String
        ext = LCase(Right(filesList(i), 4))
        If ext = ".pdf" Then
            pdfCount = pdfCount + 1
            pdfFiles.Add filesList(i)
            fileOrder(i) = "PDF"
            fileIndex(i) = pdfCount
        Else
            imgCount = imgCount + 1
            imageFiles.Add filesList(i)
            fileOrder(i) = "IMG"
            fileIndex(i) = imgCount
        End If
    Next i
    
    ' ---- Конвертируем каждую картинку в отдельный PDF через PowerPoint ----
    Dim tempPDFs As New Collection  ' Все временные PDF в правильном порядке
    
    If imgCount > 0 Then
        Dim pptApp As Object, wasOpen As Boolean
        
        On Error Resume Next
        Set pptApp = GetObject(, "PowerPoint.Application")
        wasOpen = Not (pptApp Is Nothing)
        On Error GoTo 0
        
        If pptApp Is Nothing Then
            Set pptApp = CreateObject("PowerPoint.Application")
            pptApp.Visible = True
        End If
        
        ' Размеры страниц (в пунктах)
        Dim pgW As Single, pgH As Single
        Select Case pageSize
            Case "1": pgW = 595.28: pgH = 841.89   ' A4
            Case "2": pgW = 841.89: pgH = 1190.55  ' A3
            Case "3": pgW = 612: pgH = 792          ' Letter
            Case "4": pgW = 0: pgH = 0              ' Авто
            Case "5": pgW = 595.28: pgH = 595.28    ' Квадрат
            Case Else: pgW = 595.28: pgH = 841.89
        End Select
        
        ' === КЛЮЧЕВОЕ ИЗМЕНЕНИЕ: каждая картинка = отдельная презентация = отдельный PDF ===
        Dim imgIdx As Long
        For imgIdx = 1 To imageFiles.Count
            
            Application.StatusBar = "Конвертация изображения " & imgIdx & "/" & imgCount & "... ☕"
            DoEvents
            
            Dim fPath As String
            fPath = imageFiles(imgIdx)
            If Dir(fPath) = "" Then GoTo SkipImage
            
            ' Создаём ОТДЕЛЬНУЮ презентацию для каждой картинки!
            ' Потому что PowerPoint — диктатор и не даёт слайдам быть разного размера
            Dim pptPres As Object
            Set pptPres = pptApp.Presentations.Add(WithWindow:=False)
            
            ' Сначала добавляем картинку чтобы узнать размер
            Dim pptSlide As Object, pptShape As Object
            Set pptSlide = pptPres.Slides.Add(1, 12) ' ppLayoutBlank
            
            Set pptShape = pptSlide.Shapes.AddPicture( _
                Filename:=fPath, LinkToFile:=False, _
                SaveWithDocument:=True, Left:=0, Top:=0)
            
            Dim imgW As Single, imgH As Single
            imgW = pptShape.Width
            imgH = pptShape.Height
            
            ' Определяем размер страницы
            Dim curW As Single, curH As Single
            
            If pageSize = "4" Then
                curW = imgW
                curH = imgH
                ' Ограничение PowerPoint ~5000 pt
                If curW > 5000 Or curH > 5000 Then
                    Dim maxDim As Single
                    maxDim = IIf(curW > curH, curW, curH)
                    Dim scaleRatio As Single
                    scaleRatio = 5000 / maxDim
                    curW = curW * scaleRatio
                    curH = curH * scaleRatio
                End If
                ' Минимальный размер
                If curW < 72 Then curW = 72
                If curH < 72 Then curH = 72
            Else
                curW = pgW
                curH = pgH
                
                ' Авто-ориентация
                Dim tmp As Single
                If orientation = "3" Then
                    If (imgW > imgH) And (curW < curH) Then
                        tmp = curW: curW = curH: curH = tmp
                    ElseIf (imgH > imgW) And (curH < curW) Then
                        tmp = curW: curW = curH: curH = tmp
                    End If
                ElseIf orientation = "2" Then
                    If curW < curH Then
                        tmp = curW: curW = curH: curH = tmp
                    End If
                End If
            End If
            
            ' Устанавливаем размер слайда (теперь это не мешает другим!)
            pptPres.PageSetup.SlideWidth = curW
            pptPres.PageSetup.SlideHeight = curH
            
            ' Масштабируем картинку
            If pageSize = "4" Then
                pptShape.LockAspectRatio = False
                pptShape.Width = curW
                pptShape.Height = curH
                pptShape.Left = 0
                pptShape.Top = 0
            Else
                Dim scX As Single, scY As Single, sc As Single
                scX = curW / pptShape.Width
                scY = curH / pptShape.Height
                sc = IIf(scX < scY, scX, scY)
                
                pptShape.LockAspectRatio = True
                pptShape.Width = pptShape.Width * sc
                pptShape.Left = (curW - pptShape.Width) / 2
                pptShape.Top = (curH - pptShape.Height) / 2
            End If
            
            ' Сохраняем как отдельный PDF
            Dim tempPdfPath As String
            tempPdfPath = tempFolder & "img_" & Format(imgIdx, "0000") & ".pdf"
            pptPres.SaveAs tempPdfPath, 32  ' ppSaveAsPDF
            pptPres.Close
            
SkipImage:
            DoEvents
        Next imgIdx
        
        ' Закрываем PowerPoint если мы его открыли
        If Not wasOpen Then
            On Error Resume Next
            pptApp.Quit
            On Error GoTo 0
        End If
    End If
    
    ' ---- Собираем все PDF в правильном порядке ----
    ' Счётчики для отслеживания текущего индекса в каждой коллекции
    Dim curImgPdf As Long: curImgPdf = 0
    Dim curPdfFile As Long: curPdfFile = 0
    
    For i = 1 To filesList.Count
        If fileOrder(i) = "IMG" Then
            curImgPdf = curImgPdf + 1
            Dim imgPdfPath As String
            imgPdfPath = tempFolder & "img_" & Format(curImgPdf, "0000") & ".pdf"
            If Dir(imgPdfPath) <> "" Then
                tempPDFs.Add imgPdfPath
            End If
        ElseIf fileOrder(i) = "PDF" Then
            curPdfFile = curPdfFile + 1
            tempPDFs.Add pdfFiles(curPdfFile)
        End If
    Next i
    
    ' ---- Объединяем все PDF ----
    If tempPDFs.Count = 0 Then
        MsgBox "Нечего объединять. Все файлы оказались пустышками! :f09f98b1:", vbExclamation
        GoTo Cleanup
    End If
    
    Application.StatusBar = "Объединение PDF... Почти готово! :f09f8f81:"
    
    If tempPDFs.Count = 1 Then
        ' Только один файл — просто копируем
        FileCopy tempPDFs(1), outputPath
    Else
        ' Объединяем через Adobe Acrobat (если есть) или через Shell
        Dim merged As Boolean
        merged = False
        
        ' Попытка 1: Adobe Acrobat Pro
        merged = MergeWithAcrobat(tempPDFs, outputPath)
        
        ' Попытка 2: PDFtk (бесплатная утилита)
        If Not merged Then
            merged = MergeWithPDFtk(tempPDFs, outputPath)
        End If
        
        ' Попытка 3: Ghostscript
        If Not merged Then
            merged = MergeWithGhostscript(tempPDFs, outputPath)
        End If
        
        ' Попытка 4: Python (если установлен)
        If Not merged Then
            merged = MergeWithPython(tempPDFs, outputPath, tempFolder)
        End If
        
        If Not merged Then
            ' Последний вариант — сохраняем отдельные файлы
            Dim fallbackFolder As String
            fallbackFolder = Left(outputPath, InStrRev(outputPath, "\"))
            
            Dim msg As String
            msg = "Не удалось объединить PDF! :f09f98a4:" & vbCrLf & vbCrLf & _
                  "Не найден ни один инструмент для склейки:" & vbCrLf & _
                  "• Adobe Acrobat Pro" & vbCrLf & _
                  "• PDFtk (pdftk.exe)" & vbCrLf & _
                  "• Ghostscript (gswin64c.exe)" & vbCrLf & _
                  "• Python с PyPDF2/pikepdf" & vbCrLf & vbCrLf & _
                  "Сохранить отдельные PDF в папку?"
            
            If MsgBox(msg, vbYesNo + vbQuestion) = vbYes Then
                Dim outFolder As String
                outFolder = Left(outputPath, InStrRev(outputPath, "\")) & "PDF_Pages\"
                On Error Resume Next
                MkDir outFolder
                On Error GoTo 0
                
                For i = 1 To tempPDFs.Count
                    Dim destFile As String
                    destFile = outFolder & "Page_" & Format(i, "000") & ".pdf"
                    FileCopy tempPDFs(i), destFile
                Next i
                
                MsgBox "Отдельные PDF сохранены в:" & vbCrLf & outFolder, vbInformation
            End If
            GoTo Cleanup
        End If
    End If
    
    Application.StatusBar = False
    MsgBox ":f09f8e89: PDF создан: " & outputPath & vbCrLf & _
           "Страниц/файлов: " & tempPDFs.Count & vbCrLf & _
           "(Картинок: " & imgCount & ", PDF: " & pdfCount & ")", vbInformation

Cleanup:
    Application.StatusBar = False
    ' Чистим временные файлы
    On Error Resume Next
    Dim f As String
    f = Dir(tempFolder & "*.*")
    Do While f <> ""
        Kill tempFolder & f
        f = Dir
    Loop
    RmDir tempFolder
    On Error GoTo 0
    
End Sub

' ============================================================
' ФУНКЦИИ ОБЪЕДИНЕНИЯ PDF
' (Четыре всадника PDF-апокалипсиса)
' ============================================================

Function MergeWithAcrobat(ByRef pdfFiles As Collection, ByVal outputPath As String) As Boolean
    ' Пытаемся использовать Adobe Acrobat Pro
    ' (Если у вас есть лицензия, вы — счастливчик!)
    
    On Error GoTo AcrobatFail
    
    Dim acroApp As Object
    Set acroApp = CreateObject("AcroExch.App")
    
    Dim primaryDoc As Object
    Set primaryDoc = CreateObject("AcroExch.PDDoc")
    
    ' Открываем первый PDF
    If Not primaryDoc.Open(pdfFiles(1)) Then GoTo AcrobatFail
    
    ' Добавляем остальные
    Dim i As Long
    For i = 2 To pdfFiles.Count
        Dim nextDoc As Object
        Set nextDoc = CreateObject("AcroExch.PDDoc")
        
        If nextDoc.Open(pdfFiles(i)) Then
            Dim numPages As Long
            numPages = nextDoc.GetNumPages
            primaryDoc.InsertPages primaryDoc.GetNumPages - 1, nextDoc, 0, numPages, False
            nextDoc.Close
        End If
        Set nextDoc = Nothing
    Next i
    
    ' Сохраняем
    primaryDoc.Save 1, outputPath  ' PDSaveFull
    primaryDoc.Close
    acroApp.Exit
    
    Set primaryDoc = Nothing
    Set acroApp = Nothing
    
    MergeWithAcrobat = True
    Exit Function
    
AcrobatFail:
    On Error Resume Next
    If Not primaryDoc Is Nothing Then primaryDoc.Close
    If Not acroApp Is Nothing Then acroApp.Exit
    Set primaryDoc = Nothing
    Set acroApp = Nothing
    On Error GoTo 0
    MergeWithAcrobat = False
End Function

Function MergeWithPDFtk(ByRef pdfFiles As Collection, ByVal outputPath As String) As Boolean
    ' PDFtk — бесплатный швейцарский нож для PDF
    ' Скачать: https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/
    
    On Error GoTo PDFtkFail
    
    ' Ищем pdftk
    Dim pdftkPath As String
    pdftkPath = FindExecutable("pdftk.exe")
    
    If pdftkPath = "" Then
        MergeWithPDFtk = False
        Exit Function
    End If
    
    ' Собираем команду
    Dim cmd As String
    cmd = """" & pdftkPath & """"
    
    Dim i As Long
    For i = 1 To pdfFiles.Count
        cmd = cmd & " """ & pdfFiles(i) & """"
    Next i
    
    cmd = cmd & " cat output """ & outputPath & """"
    
    ' Запускаем и ждём
    Dim exitCode As Long
    exitCode = RunAndWait(cmd)
    
    MergeWithPDFtk = (Dir(outputPath) <> "")
    Exit Function
    
PDFtkFail:
    MergeWithPDFtk = False
End Function

Function MergeWithGhostscript(ByRef pdfFiles As Collection, ByVal outputPath As String) As Boolean
    ' Ghostscript — олдскульный, но надёжный как танк
    
    On Error GoTo GSFail
    
    Dim gsPath As String
    gsPath = FindExecutable("gswin64c.exe")
    If gsPath = "" Then gsPath = FindExecutable("gswin32c.exe")
    
    If gsPath = "" Then
        MergeWithGhostscript = False
        Exit Function
    End If
    
    Dim cmd As String
    cmd = """" & gsPath & """ -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite" & _
          " -sOutputFile=""" & outputPath & """"
    
    Dim i As Long
    For i = 1 To pdfFiles.Count
        cmd = cmd & " """ & pdfFiles(i) & """"
    Next i
    
    Dim exitCode As Long
    exitCode = RunAndWait(cmd)
    
    MergeWithGhostscript = (Dir(outputPath) <> "")
    Exit Function
    
GSFail:
    MergeWithGhostscript = False
End Function

Function MergeWithPython(ByRef pdfFiles As Collection, ByVal outputPath As String, _
                         ByVal tempFolder As String) As Boolean
    ' Python — потому что почему бы и нет?
    ' Нужен PyPDF2 или pikepdf: pip install PyPDF2
    
    On Error GoTo PythonFail
    
    Dim pythonPath As String
    pythonPath = FindExecutable("python.exe")
    If pythonPath = "" Then pythonPath = FindExecutable("python3.exe")
    
    If pythonPath = "" Then
        MergeWithPython = False
        Exit Function
    End If
    
    ' Создаём Python-скрипт
    Dim scriptPath As String
    scriptPath = tempFolder & "merge_pdf.py"
    
    Dim f As Integer
    f = FreeFile
    Open scriptPath For Output As #f
    
    Print #f, "import sys"
    Print #f, "try:"
    Print #f, "    from PyPDF2 import PdfMerger"
    Print #f, "    merger = PdfMerger()"
    
    Dim i As Long
    For i = 1 To pdfFiles.Count
        Print #f, "    merger.append(r'" & Replace(pdfFiles(i), "'", "\'") & "')"
    Next i
    
    Print #f, "    merger.write(r'" & Replace(outputPath, "'", "\'") & "')"
    Print #f, "    merger.close()"
    Print #f, "    print('OK')"
    Print #f, "except ImportError:"
    Print #f, "    try:"
    Print #f, "        import pikepdf"
    Print #f, "        pdf = pikepdf.Pdf.new()"
    
    For i = 1 To pdfFiles.Count
        Print #f, "        src = pikepdf.Pdf.open(r'" & Replace(pdfFiles(i), "'", "\'") & "')"
        Print #f, "        pdf.pages.extend(src.pages)"
    Next i
    
    Print #f, "        pdf.save(r'" & Replace(outputPath, "'", "\'") & "')"
    Print #f, "        print('OK')"
    Print #f, "    except ImportError:"
    Print #f, "        print('FAIL')"
    Print #f, "        sys.exit(1)"
    Print #f, "except Exception as e:"
    Print #f, "    print(f'ERROR: {e}')"
    Print #f, "    sys.exit(1)"
    
    Close #f
    
    ' Запускаем
    Dim cmd As String
    cmd = """" & pythonPath & """ """ & scriptPath & """"
    
    Dim exitCode As Long
    exitCode = RunAndWait(cmd)
    
    MergeWithPython = (Dir(outputPath) <> "")
    Exit Function
    
PythonFail:
    MergeWithPython = False
End Function

' ============================================================
' ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ
' ============================================================

Function FindExecutable(ByVal exeName As String) As String
    ' Ищем исполняемый файл в PATH и типичных местах
    
    Dim testPaths As Variant
    testPaths = Array( _
        exeName, _
        "C:\Program Files\PDFtk\bin\" & exeName, _
        "C:\Program Files (x86)\PDFtk\bin\" & exeName, _
        "C:\Program Files\gs\gs10.02.1\bin\" & exeName, _
        "C:\Program Files\gs\gs10.01.2\bin\" & exeName, _
        "C:\Program Files\gs\gs10.00.0\bin\" & exeName, _
        "C:\Program Files\gs\gs9.56.1\bin\" & exeName, _
        "C:\Program Files (x86)\gs\gs9.56.1\bin\" & exeName, _
        Environ("LOCALAPPDATA") & "\Programs\Python\Python312\" & exeName, _
        Environ("LOCALAPPDATA") & "\Programs\Python\Python311\" & exeName, _
        Environ("LOCALAPPDATA") & "\Programs\Python\Python310\" & exeName, _
        "C:\Python312\" & exeName, _
        "C:\Python311\" & exeName, _
        "C:\Python310\" & exeName _
    )
    
    ' Сначала проверяем через WHERE (для файлов в PATH)
    Dim tempFile As String
    tempFile = Environ("TEMP") & "\vba_which_" & Replace(exeName, ".", "_") & ".txt"
    
    On Error Resume Next
    Shell "cmd /c where " & exeName & " > """ & tempFile & """ 2>nul", vbHide
    
    ' Даём время на выполнение
    Dim waitStart As Single
    waitStart = Timer
    Do While Timer - waitStart < 2
        DoEvents
        If Dir(tempFile) <> "" Then
            If FileLen(tempFile) > 0 Then Exit Do
        End If
    Loop
    
    If Dir(tempFile) <> "" Then
        If FileLen(tempFile) > 0 Then
            Dim f As Integer
            f = FreeFile
            Dim line As String
            Open tempFile For Input As #f
            If Not EOF(f) Then
                Line Input #f, line
                line = Trim(line)
                If line <> "" And Dir(line) <> "" Then
                    Close #f
                    Kill tempFile
                    FindExecutable = line
                    Exit Function
                End If
            End If
            Close #f
        End If
        Kill tempFile
    End If
    On Error GoTo 0
    
    ' Проверяем известные пути
    Dim p As Variant
    For Each p In testPaths
        If p <> exeName Then  ' Пропускаем голое имя
            On Error Resume Next
            If Dir(CStr(p)) <> "" Then
                FindExecutable = CStr(p)
                Exit Function
            End If
            On Error GoTo 0
        End If
    Next p
    
    FindExecutable = ""
End Function

Function RunAndWait(ByVal cmd As String) As Long
    ' Запускает команду и ждёт завершения
    
    Dim wsh As Object
    Set wsh = CreateObject("WScript.Shell")
    
    RunAndWait = wsh.Run("cmd /c " & cmd, 0, True)  ' 0 = скрытое окно, True = ждать
    
    Set wsh = Nothing
End Function
WEB API или другие способы подключения к PDF Creator 24
 
Цитата
написал:
Может кто-то заморачивался подобным?
заморачивался) решение выше.
WEB API или другие способы подключения к PDF Creator 24
 
Можно без апи.

Вот пример конвертера (будет работать , если на компе стоит power point)

5. Alt+F8 → выберите "ConvertImagesToPDF" → выполнить.

Пример excel приложен. (запустить макрос, выбрать картинки (можно разных форматов), слепить все в один pdf (по мере выполнения процедуры показать куда и под каким именем сохранить pdf)


Процедура:
Код
Sub ConvertImagesToPDF_Advanced()
    
    Dim fd As FileDialog
    Dim filesList As New Collection
    Dim i As Long
    Dim outputPath As String
    
    ' ---- Выбор картинок ----
    Set fd = Application.FileDialog(msoFileDialogFilePicker)
    With fd
        .Title = "Выберите изображения"
        .AllowMultiSelect = True
        .Filters.Clear
        .Filters.Add "Изображения", "*.jpg;*.jpeg;*.png;*.bmp;*.gif;*.tif;*.tiff"
        If .Show <> -1 Then Exit Sub
        For i = 1 To .SelectedItems.Count
            filesList.Add .SelectedItems(i)
        Next i
    End With
    
    ' ---- Настройки через UserForm-заменитель (InputBox) ----
    Dim pageSize As String
    pageSize = InputBox("Выберите размер страницы:" & vbCrLf & vbCrLf & _
                        "1 - A4 (210 x 297 мм)" & vbCrLf & _
                        "2 - A3 (297 x 420 мм)" & vbCrLf & _
                        "3 - Letter (216 x 279 мм)" & vbCrLf & _
                        "4 - Подогнать под размер картинки" & vbCrLf & _
                        "5 - Квадрат (210 x 210 мм)", _
                        "Настройки PDF", "1")
    
    If pageSize = "" Then Exit Sub
    
    Dim orientation As String
    orientation = InputBox("Ориентация страницы:" & vbCrLf & vbCrLf & _
                           "1 - Книжная (портрет)" & vbCrLf & _
                           "2 - Альбомная (ландшафт)" & vbCrLf & _
                           "3 - Авто (по ориентации картинки)", _
                           "Ориентация", "3")
    
    If orientation = "" Then Exit Sub
    
    ' ---- Путь сохранения ----
    outputPath = Application.GetSaveAsFilename( _
        InitialFileName:="Output.pdf", _
        FileFilter:="PDF (*.pdf), *.pdf", _
        Title:="Сохранить PDF")
    
    If outputPath = "False" Then Exit Sub
    If LCase(Right(outputPath, 4)) <> ".pdf" Then outputPath = outputPath & ".pdf"
    
    ' ---- Создание PDF ----
    Application.StatusBar = "Создание PDF..."
    
    Dim pptApp As Object, pptPres As Object
    Dim pptSlide As Object, pptShape As Object
    Dim wasOpen As Boolean
    
    On Error Resume Next
    Set pptApp = GetObject(, "PowerPoint.Application")
    wasOpen = Not (pptApp Is Nothing)
    On Error GoTo 0
    
    If pptApp Is Nothing Then
        Set pptApp = CreateObject("PowerPoint.Application")
        pptApp.Visible = True
    End If
    
    Set pptPres = pptApp.Presentations.Add(WithWindow:=False)
    
    ' Размеры страниц (в пунктах, 1 мм ≈ 2.835 pt)
    Dim pgW As Single, pgH As Single
    Select Case pageSize
        Case "1": pgW = 595.28: pgH = 841.89   ' A4
        Case "2": pgW = 841.89: pgH = 1190.55  ' A3
        Case "3": pgW = 612: pgH = 792          ' Letter
        Case "4": pgW = 0: pgH = 0              ' Авто
        Case "5": pgW = 595.28: pgH = 595.28    ' Квадрат
        Case Else: pgW = 595.28: pgH = 841.89
    End Select
    
    For i = 1 To filesList.Count
        
        Application.StatusBar = "Обработка " & i & "/" & filesList.Count & "..."
        DoEvents
        
        Dim fPath As String
        fPath = filesList(i)
        If Dir(fPath) = "" Then GoTo SkipFile
        
        ' Сначала нужно узнать размер картинки для режима "Авто"
        ' Создаём временный слайд для получения размеров
        Dim tempSlide As Object
        Set tempSlide = pptPres.Slides.Add(pptPres.Slides.Count + 1, 12)
        
        Set pptShape = tempSlide.Shapes.AddPicture( _
            FileName:=fPath, LinkToFile:=False, _
            SaveWithDocument:=True, Left:=0, Top:=0)
        
        Dim imgW As Single, imgH As Single
        imgW = pptShape.Width
        imgH = pptShape.Height
        
        ' Определяем размер слайда
        Dim curW As Single, curH As Single
        
        If pageSize = "4" Then
            ' Подгоняем слайд под картинку (макс 5000 pt ограничение PPT)
            curW = imgW
            curH = imgH
            ' Ограничиваем максимальный размер
            If curW > 5000 Or curH > 5000 Then
                Dim maxDim As Single
                maxDim = IIf(curW > curH, curW, curH)
                Dim ratio As Single
                ratio = 5000 / maxDim
                curW = curW * ratio
                curH = curH * ratio
            End If
        Else
            curW = pgW
            curH = pgH
            
            ' Авто-ориентация
            If orientation = "3" Then
                ' Если картинка альбомная, а страница книжная — переворачиваем
                If (imgW > imgH) And (curW < curH) Then
                    Dim tmp As Single
                    tmp = curW: curW = curH: curH = tmp
                ElseIf (imgH > imgW) And (curH < curW) Then
                    tmp = curW: curW = curH: curH = tmp
                End If
            ElseIf orientation = "2" Then
                ' Принудительно альбомная
                If curW < curH Then
                    tmp = curW: curW = curH: curH = tmp
                End If
            End If
        End If
        
        ' Удаляем временный слайд
        pptShape.Delete
        tempSlide.Delete
        
        ' Устанавливаем размер слайда (PowerPoint меняет для всех слайдов,
        ' но при экспорте в PDF это работает корректно для последнего размера)
        ' Для разных размеров страниц — используем единый размер
        pptPres.PageSetup.SlideWidth = curW
        pptPres.PageSetup.SlideHeight = curH
        
        ' Добавляем слайд
        Set pptSlide = pptPres.Slides.Add(pptPres.Slides.Count + 1, 12)
        
        ' Вставляем картинку
        Set pptShape = pptSlide.Shapes.AddPicture( _
            FileName:=fPath, LinkToFile:=False, _
            SaveWithDocument:=True, Left:=0, Top:=0)
        
        ' Масштабируем
        Dim scX As Single, scY As Single, sc As Single
        
        If pageSize = "4" Then
            ' Растягиваем на весь слайд
            pptShape.LockAspectRatio = False
            pptShape.Width = curW
            pptShape.Height = curH
            pptShape.Left = 0
            pptShape.Top = 0
        Else
            scX = curW / pptShape.Width
            scY = curH / pptShape.Height
            sc = IIf(scX < scY, scX, scY)
            
            pptShape.LockAspectRatio = True
            pptShape.Width = pptShape.Width * sc
            ' Центрируем
            pptShape.Left = (curW - pptShape.Width) / 2
            pptShape.Top = (curH - pptShape.Height) / 2
        End If
        
SkipFile:
    Next i
    
    ' Экспорт
    If pptPres.Slides.Count > 0 Then
        Application.StatusBar = "Экспорт в PDF..."
        pptPres.SaveAs outputPath, 32  ' ppSaveAsPDF
        
        pptPres.Close
        If Not wasOpen Then pptApp.Quit
        
        Application.StatusBar = False
        MsgBox "PDF создан: " & outputPath & vbCrLf & _
               "Страниц: " & filesList.Count, vbInformation
    Else
        pptPres.Close
        If Not wasOpen Then pptApp.Quit
        Application.StatusBar = False
        MsgBox "Нет изображений для экспорта!", vbExclamation
    End If
    
End sub
WEB API или другие способы подключения к PDF Creator 24
 
можно без dll. у power point есть варианты преобразования внутренними средствами. Пошукаю. то есть в офисе есть библы которые могут сделать это без внешних апи.
Искусственный интеллект (ИИ) на службе Excel, Искусственный интеллект напишет код макроса, формулы, функции и тд.
 
Ради интереса пробежался по всем форумам по vba excel,access. Не был тут вообще пипец сколько лет. Интересно стало, как поживают форумы при активном наступлении ИИ. Да по ходу потихоньку отмирать начинают. По теме ветке - да, ИИ уже пишет код лучше чем 98 процентов разработчиков. Причем можно обьяснить чего хочется на выходе обычным простым человеческим языком. Повезло тем, кто досконально успел изучить программирование до наступления ИИ (так как качать в первую очередь надо ту нейросеть, которая между своими ушами)) vba был первенцем из языков , который я выучил досконально до красной глины. (первым из 4х других). Так и хочется сказать типа такого - vba жив, или чет типа vba поднимается с колен итд итп, но тенденция такова что все идет в сторону упрощения. Поживем увидим. В качестве прикола, и шуточного лозунга "vba поднимается с колен" запилил в excel игрушку , космический 2d шутер (начинал писать еще в далеком 2018 году). В общем вот чего может vba, причем чистый. полноценный шутан на чистом vba: https://www.youtube.com/watch?v=0ppJxh_nWic   Я сознательно поднял планку работы\игры, чтобы показать уровень , что не всегда ИИ поможет (Старожилы сайта поймут уровень работы). Или не так даже, чем больше ты знаешь матчасть, тем больше выхлоп от ИИ. Уровень такой , что даже вайбкод не даст эффекта в ИИ, если ты не шаришь в vba, или плохо шаришь. В общем дядьки и тетьки, качаем свою собственную нейронку которая в голове, она по прежнему остается нашим самым ценным депозитом.
Изменено: Лалыч - 26.03.2026 21:06:53
Загрузка файла через Excel в БД Access в поле "Вложения"
 
Привет от собратьев по разуму.
Вопрос был задан там тоже и ответ я написал тоже там:)
https://www.sql.ru/forum/1333449/zagruzka-fayla-cherez-excel-v-bd-access-v-pole-vlozheniya
Запись отфильтрованных значений массива в другой массив, vba,arrays
 
Андрей, спасибо большое!

Я накололся и немного недожал счетчик, вместо вашего:
Код
If arr(i, 3) <> 0 Then            
For x = 1 To 3
 arr2(lr, x) = arr(i, x)
    Next
    lr = lr + 1
         End If
Я его пытался крутить тут:)
Код
If arr(i, 3) <> 0 Then            
For x = 1 To 3
 arr2(lr, x) = arr(i, x)
 lr = lr + 1
          Next
         End If

Эх, два часа убил . Точно, у нас же надо на уровне строки прибавлять, не заметил сразу свой косяк. Еще раз спасибо!
Запись отфильтрованных значений массива в другой массив, vba,arrays
 
То что циклом понятно)

1) При нажатии на кнопку в первый массив с размерностью arr(1 to 9,1 to 3) записываются данные из таблички с активного листа.
2) Создается второй целевой массивnew_array(1 to 4,1 to 3) куда надо поместить отфильтрованные строки из первого
А вот как циклом зафигачить из первого во второй ,что то не выходит, глаз замылился.
Размеры второго я сознательно уже подогнал под количество строк с учетом выборки. Чтобы сэкономить время на решение.
Вот тестовый код на чем остановился
Код
Private Sub CommandButton1_Click()
Dim arr(1 To 9, 1 To 3)
'заполняем первый массив. 1 мера - строки, 2ая - стобцы
For i = LBound(arr, 1) To UBound(arr, 1)
For j = LBound(arr, 2) To UBound(arr, 2)
arr(i, j) = Cells(i, j)
Next
Next
'подготавливаем второй  массив arr_report. 1 мера - строки, 2ая - стобцы
Dim arr_report() 
ReDim arr_report(1 To 4, 1 To 3)
'здесь нужно циклом обойти первый и добавить во второй массив уникальные строки по которым Код<>0


End Sub

Файл также приложил, при нажатии на кнопку должен заполняться массив   new_array(1 to 4,1 to 3) отфильтрованными значениями из первого arr(1 to 9,1 to 3)
Прошу помочь.
Изменено: Лалыч - 11.01.2021 15:25:51
Запись отфильтрованных значений массива в другой массив, vba,arrays
 
Здравствуйте, возник небольшой вопрос добавления отфильтрованных значений из одного двумерного массива, в другой .
Есть двумерный массив VBA , который содержит в себе небольшую табличку (он у меня уже заполнен и содержит данные):
ТоварЦенаКод
яблоко25код1
яблоко00
яблоко00
дыня69код1
дыня00
ананас2код3
яблоко00
ананас00
Необходимо добавить в новый 2 массив new_array из первого arr(1 to 9,1 to 3) только те строки, по которым столбец Код не равен 0.
Размерность нового массива new_array(1 to 4,1 to 3) соответственно.

Подскажите как отфильтровать первый массив и добавить во второй 4 строки (это те строки по которым значение столбца Код <>0 включая первую строку заголовок)
Цветной API-прямоугольник на UserForm. Создаем progressbar
 
Цитата
AndyGrouve написал:
Здравствуйте.Используя API-функцию Rectangle из библиотеки "gdi32", рисую на пользовательской форме прямоугольник. Прямоугольник выводится с белой заливкой. Т.к. нужна заливка другого цвета, ничего личше чем по-пиксельную закраску (функция SetPixel)
Вы в конечном итоге случайно не хотите сделать что то похожее на прогресс бар?  где по мере исполнения задачи увеличивается закрашенная шкала/прогресс выполнения кода?
Если так, то можно абстаргироваться от API функций и реализовать при помощи встроенного контрола типа label на форме.
Проигрывание аудио из интернета VBA
 
Спасибо!)  
Проигрывание аудио из интернета VBA
 
Уважаемые единомышленники, всем привет!
Подскажите пожалуйста, есть ли возможность в VBA (рассматриваю любые библиотеки) проигрывать потоковое аудио из интернета.
К примеру сослаться на адрес аудиозаписи в ВК, или еще каком ресурсе.
Excel и Access могут облегчить друг другу жизнь?, как можно совмещать их способности
 
Цитата
JeyCi написал:
вы бы нормализовали вашу бд в Access...
Уже столько копий сломано на эту тему и споров пройдено. Помимо нормализации как таковой, есть еще так называемый уровень нормализации. То есть либо ты идешь с позиции создания единого универсального справочника и комплектуешь все по возможности в одну таблицу , либо каждый бизнес элемент (блок) важный для раздельной аналитики и обработки выделяешь в отдельную сущность. Это значительно ускоряет работу запросов и упрощает восприятие архитектуры СУБД для последователей.
Вы просто не шарите о чем говорите, потому что большого практического опыта в создании баз данных у вас нет)
Excel и Access могут облегчить друг другу жизнь?, как можно совмещать их способности
 
Да, конечно, для нормальной скорости и защиты данных ,сами базы только на SQL . Акс только как клиент, да и эксель тоже. Вопрос как лучше экселю работать с SQL больше философский. Можно в экселе писать запросы к серверу, можно с сервера выгружать в эксель нарезанные данные. Тут дело вкуса. Можно запилить отдельную статью опросник, но в этом направлении проблем нет в общем то.
Excel и Access могут облегчить друг другу жизнь?, как можно совмещать их способности
 
Если говорим про первую, то обычная разделенная, без посадки на сервер. Попросили сделать в классическом варианте, чтобы потом можно было в случае чего подпиливать силами местных умников. Серверная часть на общем файловом ресурсе. Но это все сознательно просили, чтобы было понятно и знакомо. И на русском еще попросили названия системных полей в таблицах. Что просили то и сделал.
С нормализацией данных и индексами неплохо заморочился, поэтому вес серверной части был небольшой, около 12мб. (с экспортированной статистикой уже, за 2 прошлых года.) Проект не очень большой , но вышел крепенько :


Остальные - на MS SQL и MySQL. Аксесс как клиент только (в случае MySQL клиент ч/з MySQL odbc driver.)  
Изменено: Лалыч - 01.10.2019 18:44:21
Excel и Access могут облегчить друг другу жизнь?, как можно совмещать их способности
 
Цитата
Юрий М написал:
Может пора что-то в консерватории поменять? (с) М. Жванецкий
Консерваторов  :D

Цитата
БМВ написал:
что VBA, Access -это днище
Ктожь говорит, что днище, около 3 лет назад написал СУБД  в Access для РАМН, для учета показателей при лечении одного из самых жестких типов рака.  Чтобы постоянно не менять структуру данных аксесса из за появляющихся новых отчетов  (просили в Excel) создал некий шаблонизатор в Excel который принимал в себя и выводил на листе результат выборки запроса SQL с необходимыми удобными сгруппированными данными для последующей генерации отчетов/диаграмм  (Экспорт в Excel из аксесса выполняется гораздо быстрей ,чем линк таблиц/вьюх в Excel из  access).  

Потом что еще по теме топика (связка access+excel) - какие практические применения. Я по роду деятельности отношусь к работникам сферы закупок , логистики, supply chain.. Непаханное поле для любителей excel и access (планирование отгрузок, расчет бюджета, аналитика эффективности поставок, ABC,XYZ анализ, моделирование стрессовых ситуаций в бизнесе, антикризисные меры и способы решения данных ситуаций. ) Все опорные модели ,с последующей защитой естественно формировались в Excel. Пульт управления экселем был реализован в аксессе.  Просто из за того что, GUI в аксессе получше.

Далее - связка Excel и Access неплохо зарекомендовала себя при генерации полного комплекта товарно сопроводительных документов для таможни и склада . Пользователи вели полный учет данных в аксессе (досталось от предшественников) , удалось малой кровью создать шаблоны и описать все вариации импортной и экспортной документации ,в зависимости от условий поставки(инкотермс)  и генерацию всего комплекта нажатием на одну кнопку. При предыдущем способе изготовления документов (45-50 минут) удалось сократить время до 1 минуты. Только на подпись оставалось отнести.

И одно из самых то главных откровений по теме топика )) Именно эта связка (а наверное просто любовь к программированию и структуризации информации), проработка бизнес модели, с последующей реализацией в и возможность алгоритмизировать и структурировать информацию в разрезе своих бизнес процессов и выдача более точных прогнозов итд итп привела к хорошему карьерному росту со всеми последующими плюшками.)
Excel и Access могут облегчить друг другу жизнь?, как можно совмещать их способности
 
Ну вот как обычно все не так поняли.
Excel и Access могут облегчить друг другу жизнь?, как можно совмещать их способности
 
По теме топика, чтобы не потерялась нить) С VBA Access ,Excel активно начал взаимодействовать с 2009 года, с тех пор компьютер не знал покоя :D  Позже захотелось большего, изучил MySQL  (так как хотелось использовать нормальную скорость и взрослую защиту данных для клиента (Excel/Access) - на уровне привилегий пользователей, плюс нормальное задание логики бизнес процессов на стороне сервера.)
Потом захотелось не привязываться к десктопному приложению и повторить функционал в web, чтобы проекты работали отовсюду через браузер, без привязки к драйверам, библиотекам . Пришлось поботанить PHP+JS+HTML.
Далее захотелось научится писать клиент серверные приложения на каком либо взрослом языке. Решил попробовать себя в роли Андроид разработчика . Пошел на курсы по JAVA (Котлин решил не трогать). После Java стало понятно, что VB,VBA Excel/Access это детские фантазии))
Если вы программист по основному роду деятельности (я кстати никакого отношения не имею к программированию по своему функционалу и должности), изучать VBA Excel/Access это еще та могилка. Excel/Access сам по себе является могилкой для программиста.
Офисный кодинг позволит слепить по быстрому заплатку в бизнес логике предприятия, помочь с красивыми отчетами, группировкой информации, накидать свою базку для решения проблем на уровне небольшого отдела компании, но не более. И если вы вдруг захотите позиционироваться как программист VBA и получать к примеру условно среднюю зарплату кодера со стажем 4-5лет - 125-130 т.р.  , то любителей VBA ждет обломинго. Средний показатель зп на рынке по VBA - 55-60 т.р.

С дополнениями функционала в виде эникейщика. Писать отдельно проекты в VBA на заказ (курсовые,лабы, контрольные в расчет не берем.) тоже занятие так себе. Студентам вы сможете конечно помочь за небольшую мзду, и сделав за неделю заказов этак тыщ на 15 наверняка тоже будете чувствовать себя героем, но это тупик, так как делая контрольные и лабы вы не развиваетесь и не работаете над реально серьезным проектом, который требует полной отдачи и соответственно нормально оплачивается. Нет также в чистом Excel /Access такого понятия как продукт, который можно сделать и продавать множество раз (ну к примеру за год на одном созданном проекте заработать 2-3 млн рублей.) Офисный кодинг не для этого.

Так что тем кто хочет реально развиваться в области кодинга с соотвествующей компенсацией своих усилий - пора расчехлять талмуды с C++,или Java, или C#, там больше движухи, больше напрягается мозг и больше плОтют. Там реально поймете для чего нужен ООП и что это такое на самом деле.  
Лучший парсер VBA-Json (ваше мнение)
 
Большое спасибо всем за ответы!

Цитата
JeyCi написал:
а самый простой - это Power Query !! без vba ... ничто с ним в сравнение не идёт...
Power Query безусловно волшебная палочка, но к сожалению (очень и очень большому) в MS Access её не завезли. Хоть сам собирай народ и выходи на митинг около главного здания Майкрософт,с просьбой включить PQ в состав MS Access ))


Цитата
sokol92 написал:
Мы используем для разбора JSON собственный скорострельный потоковый парсер (для посимвольного анализа JSON применяя фрагмент кода из процитированной ссылки).
Есть даже отдельные сервера , которые только и заточены под это)

В общем еще раз огромное спасибо за участие в обсуждении, буду экспериментировать, материала собрал много.
Лучший парсер VBA-Json (ваше мнение)
 
Да, спасибо,видал) Это самая большая и проработанная библиотека в плане парсинга json. Там есть все возможные сценарии и возможность создать любой шаблон. Но она при определенных условиях подлипает и замедляет работу приложения (Что в экселе,что в аксессе. В Экселе при большом количестве записей начинает тупить безбожно. В аксессе ситуация по скорости процентов на 25-30 получше, но тоже не нравиться.) Возможно удастся немного подпилить, работаю над этим)

Во время поисков библиотек параллельно нашел самый краткий и простой формат обработки json. Вот ,могу поделиться, для экселя как раз идеально подходит. На русскоязычных сайтах не нашел, на одном зарубежном . Все гениальное просто, всего семь строк самого парсера. Он не обрабатывает по умолчанию проблемные значения в Json, но приятен с позиции восприятия программиста VBA . В принципе я его подточил немного, вот код:
Код
Private Sub CommandButton1_Click()
' ВЫВОДИТ JSON В ЯЧЕЙКИ EXCEL
Dim str As Variant, N&, R&
Dim xmlhttp As New MSXML2.XMLHTTP60 ' не забудьте подключить в библиотеках ' tools -> references
Dim URL As String
Dim user As String
Dim password As String

user = Cells(6, "H") 'ячейка для ввода логина
password = Cells(7, "H") 'ячейка для ввода пароля
URL = "http://localhost/json_test/simpleJson.php"  ' путь до страницы ,где выводится json

If user = "" Or password = "" Then
MsgBox "Заполните поля логин и пароль"
Exit Sub
End If

argumentString = "user=" & user & "&password=" & password

        xmlhttp.Open "POST", URL, False ' открываем соединение
        xmlhttp.setRequestHeader "Content-type", "application/x-www-form-urlencoded" '
        xmlhttp.send argumentString
        'MsgBox xmlhttp.responseText, vbInformation, "ЭТО ВЫВОД СЫРОГО JSON НА ЭКРАН! НАЖМИТЕ ОК.
  ' НАЧАЛО ПАРСЕРА
        str = Split(xmlhttp.responseText, "{""client_id"":") 'client_id - имя ключевого поля из таблицы, первое, с чего начинается само тело Json
    N = UBound(str)
    For R = 1 To N
        Cells(R + 1, 1) = Split(Split(str(R), "company_name"":""")(1), """")(0) ' R+1 - выгрузка в ячейки начинается со второй строки
        Cells(R + 1, 2) = Split(Split(str(R), "telefone"":""")(1), """")(0)
        Cells(R + 1, 3) = Split(Split(str(R), "e_mail"":""")(1), """")(0)
    Next R
    ' КОНЕЦ ПАРСЕРА
    
    
Exit Sub
10: MsgBox Err.Description
End Sub


И написал под него небольшой тестовый код PHP на стороне веб сервера (выгрузка происходит из небольшой тестовой таблицы в базе на MySQL):

Код
<?php

if (empty($_POST['user']) || empty($_POST['password']))  
{
echo "Заполните поля логин и пароль!";  
} 
else 
{
    $log= $_POST['user'];
    $pass=$_POST['password'];
    
   try {
     $dbh = new PDO('mysql:host=localhost;charset=utf8;dbname=test_db', $log, $pass);
     $response = $dbh->query("SELECT * FROM tbl_clients")->fetchAll(PDO::FETCH_ASSOC);
    
    foreach ($response as $row)
        {
        print json_encode($row,JSON_UNESCAPED_UNICODE);  
        }
} catch (PDOException $e) {
    print "Error!: " . $e->getMessage();
   // die();
}

  }
?>
Изменено: Лалыч - 20.09.2019 17:46:31
Лучший парсер VBA-Json (ваше мнение)
 
sokol92,

Отлично, спасибо! Сейчас потестим и ваш вариант :idea:
Но ваш пример это функция encode , то есть вывода данных к примеру с листа экселя и передачу его к примеру на сервер.)

Парсер это наоборот-когда вы декодируете сообщение , получаемое из определенного источника (в частности с сайта, или текстового источника.)
Изменено: Лалыч - 20.09.2019 16:08:40
Лучший парсер VBA-Json (ваше мнение)
 
Да, в этот плане попроще, выводимый Json имеет четкую структуру, порядок и количество выводимых полей не меняется. Но присутствуют запрещенные /нерекомендуемые значки в самих значениях: "  '  // / \ {}} И их как то надо обработать.
C VBA уже достаточно давно ,больше 10 лет,проблем нет, прошу подсказать самый крутой по вашему мнению парсер VBA -> Json (Можно в виде класса, функции, чего угодно) Ключевое требование, чтобы мог справляться с нестандартными данными в значениях выводимых полей в Json.
Лучший парсер VBA-Json (ваше мнение)
 
Приветствую всех! Подскажите пожалуйста, какой по вашему мнению лучший парсер в связке VBA-Json?

Есть одно условие, с которым мне придется смириться к сожалению, не от меня зависит- в ответах Json время от времени будут попадаться в полях (в значениях полей ,выгружаемых в Json) символы типа таких: "  '  // / \ {}} .  и прочие кракозябры.
Автоматическое добавление даты в определённую ячейку через VBA
 
Ок, спасибо, я с вашим интерфейсом сайта просто пока не освоился.
Изменено: Сергей Лалов - 26.07.2013 12:21:25
Автоматическое добавление даты в определённую ячейку через VBA
 
Так, вот совсем упростил:

Код
Private Sub Worksheet_Change(ByVal Target As Range)

Dim GetDateTime
' (+14400 s)
Dim t#
With CreateObject("MSXML2.XMLHTTP" ;) 
.Open "sntp", "http://www.direct-time.ru/track.php?id=time_utc", 0
.send
t = .responseText / 1000
GetDateTime = DateAdd("s", t + 14400, #1/1/1970#)
End With

If Target(1, 1).Column = 1 Then Target(1, 2).Value = GetDateTime 
'где Target(1, 1).Column = 1 изменение ловится в первом столбце
' где Target(1, 2).Value = GetDateTime значение московского времени вставляется во второй
End Sub

Образец приложил
Изменено: Сергей Лалов - 26.07.2013 11:14:25
Автоматическое добавление даты в определённую ячейку через VBA
 
Код
Private Sub Worksheet_Change(ByVal Target As Range) 
' а теперь совместим вставку данных московского текущего времени и процедуру изменения ячейки:
 
 Dim GetDateTime
 'Москва (+14400 s)
 Dim t#
 With CreateObject("MSXML2.XMLHTTP" ;)  
 .Open "sntp", "http://www.direct-time.ru/track.php?id=time_utc", 0
 .send
 t = .responseText / 1000
 GetDateTime= DateAdd("s", t + 14400, #1/1/1970#)
 End With

 
 For Each cell in Target 'проходим по всем измененным ячейкам
 If Not Intersect(cell, Range("A2:N1000" ;)  Is Nothing Then 
 With Range("O" & cell.row)
 .Value = GetDateTime
 .EntireColumn.AutoFit 
 End With
 End If
 Next cell
End Sub


Вот и все, надеюсь ответ на вопрос дал.

P.S. Привет всем с сайта про MS Access  :)
Изменено: Сергей Лалов - 25.07.2013 21:48:12
Автоматическое добавление даты в определённую ячейку через VBA
 
Получил вопрос от автора топика , но уже Вконтакте.

Вопрос заключается на самом деле в следующем- Необходимо при изменении значения ячейки поля (к примеру А1) выводить в соседней ячейке (к примеру B1 ) текущее значение времени в формате Now() , но обязательно всегда чтобы отображалось Московское Время, независимо от региона ввода - Нью Йорк это будет, Новосибирск или Пекин.
Проблему решил интересным способом, на изменение значения ячейки можно повесить следующую процедуру:

Код
Public Function GetDateTime()
 'Москва (+14400 s)
 Dim t#
 With CreateObject("MSXML2.XMLHTTP" ;) 
 .Open "sntp", "http://www.direct-time.ru/track.php?id=time_utc", 0
 .send
 t = .responseText / 1000
 GetDateTime = DateAdd("s", t + 14400, #1/1/1970#)
 End With
End Function




При изменении ячейки можно обращаться к данной процедуре в качестве вставляемого параметра. Данный код обращается к сайту эталону и выгребает оттуда данные по московскому времени с точностью до секунды.
словить событие dblclick по вертикальному диапазону ячеек одного столбца.
 
Ребят, большое спасибо!!! Выручили. Ларчик просто открывался оказывается. А если этот диапазон постоянно будет прирастать вниз новыми значениями? То есть со временем количество строк постоянно будет увеличиваться динамически. Как задать,чтобы нижний предел конечной строки был плавающим и к примеру не зависел от A10? Циклом надо предварительно прогонять весь диапазон и определять границы и только потом передавать в качестве переменной в выражение ("A2:переменная_моя")? Прошу заранее извинить за ламерские вопросы, ибо подкован в aсcess vba , с экселевскими кузявностями не так часто сталкиваюсь). Тут в принципе облегченные условия. можно сказать что поле "значение" по определению не может быть пустым (где то незаполненным), так как источником значений данного поля служит поле типа PRYMARY KEY и  AUTO_INCREMENT c MS SQL server.
словить событие dblclick по вертикальному диапазону ячеек одного столбца.
 
Привет всем!  
Возник немного нестандартный вопрос по использованию EXCEL+VBA  
Представьте себе вертикальный диапазон поля "ЗНАЧЕНИЕ" в рамках одного столбца:  
ЗНАЧЕНИЕ  
23  
65  
45  
12  
78  
96  
54  
14  
96  
12  
87  
 
Подскажите пожалуйста, как можно организовать вывод сообщения в формате msgbox()значения текущей  
ячейки данного столбца при двойном нажатии левой кнопки мыши на любом значении в данном столбце.  
 
В экселе нет таких понятий как рекордсет и текущая запись формы как понимаю. Как можно в нем зацепиться зацепится и вытащить на dblclick значение текущей ячейки?
Убрать лишние символы
 
...  
<EM><STRONG>Файл удален</STRONG> - велик размер - [<STRONG>МОДЕРАТОРЫ</STRONG>]</EM>
Страницы: 1 2 След.
Наверх