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

Страницы: 1 2 3 4 5 6 7 8 След.
Как макросом в модулях вызвать макрос из листов?
 
Цитата
Михаил написал:
А листы с кнопками рисуются не для того, чтоб их юзеры меняли туда-сюда
Зря Вы так о юзерах, эти товарищи очень любопытные и зачастую лезут куда попало. Ексель в плане защиты очень слаб.
Как макросом в модулях вызвать макрос из листов?
 
Цитата
Михаил написал:
Лист1.CommandButton1_Click
Если изменится название листа, опять работать не будет
Вам же во втором посту написали
Цитата
vikttur написал:
В модулях листов должны бытть макросы событий. Остальное - в общий модуль. Тогда не будут возникать такие вопросы.
В модуле листа
Код
Private Sub CommandButton1_Click()
  Call PressButton1
End Sub

В общем модуле
Код
Public Sub PressButton1()
  MsgBox "Кнопка 1 нажата"
End Sub
Так правильно будет
Ускорить макрос для переноса данных при совпадении кодов.
 
Цитата
Marat Ta написал:
а(ii,2) выдает ошибку вне диапазона.
У вас массив имеет размерность 1 to 30, 1 to 1.
То есть 30 строк один столбец.
Вы обращаетесь к массиву а(ii,2), ко второму столбцу которого нет.
Vba раскраска заметки вставляемой из excel в word
 
Цитата
Antykiller написал:
Set wa=Create.Object("Word.Application")
У вас уже здесь ошибка при создании объекта, как вы могли пройти дальше, до исполнения этой строки "wd.Bookmarks.item(marker).range.HighLightColorIndex=wdYellow", возможно даже не тестили.
Код подправил, скачайте файлы и положите их в одну папку.
При загрузке программы, Ексель уходит в ошибку., Прекращена работа программы Microsoft Excel
 
Добрый день, уважаемые форумчане.
Хочу выразить благодарность Всем, кто откликнулся, благодаря вашим подсказкам декларации WinApi более детально изучены и переосмыслены.

Что касается первого поста с основным вопросом по сбою программы, была проведена работа по поиску возникающей ошибки:
- переписаны WinApi, также в процессе было полное отключение всех WinApi вместе с вызовами их функций, форма стала менее красивой и функциональной, но сбой остался, могу с уверенностью сказать WinApi были не причем;
- частично изменен и переписан код (логика) загрузки формы, не помогло (прикольно смотреть на свой код спустя несколько лет,  думаю сейчас лучше стало, но время покажет.);
- написан класс логирования загрузки программы, который помог найти участок кода со странной на мой взгляд причиной, а именно после инициализации и загрузки формы выполнялась загрузка данных в листбоксы и комбобоксы, в один из листбоксов загружался текст
Код
If .cmbxOptionService.ListCount = 0 Then
      .cmbxOptionService.AddItem "Витяг з Річного плану закупівель по підрозділам"
      .cmbxOptionService.AddItem "Зміни в річний план закупівель"
      .cmbxOptionService.AddItem "Звіт по проведеним договорам"
      .cmbxOptionService.ListIndex = 0
End If
Где  len ("Витяг з Річного плану закупівель по підрозділам") =  47
на этой строке возникал сбой  :(
Заменив строку на .cmbxOptionService.AddItem "Витяг з РПЗ по підрозділам"  len ("")  =  26
Также
Код
'   If .cmbxRadioOnline.ListCount = 0 Then
'      ReDim arr(1 To 5, 1 To 2)
'      arr(1, 1) = "ROKS FM"
'      arr(1, 2) = "http://online-radioroks.tavrmedia.ua/RadioROKS_HD"
'      arr(2, 1) = "Record"
'      arr(2, 2) = "http://online.radiorecord.ru:8101/rr_128"
'      arr(3, 1) = "Кисс ФМ Украина"
'      arr(3, 2) = "http://online-kissfm.tavrmedia.ua/KissFM"
'      arr(4, 1) = "Хит ФМ Украина"
'      arr(4, 2) = "http://online-hitfm.tavrmedia.ua/HitFM"
'      arr(5, 1) = "Просто Радио"
'      arr(5, 2) = "http://62.80.190.246:8000/PRK128"
'      .cmbxRadioOnline.ColumnWidths = "90;1"
'      .cmbxRadioOnline.List = arr
'      .cmbxRadioOnline.ListIndex = 0
'   End If
 len("http://online-radioroks.tavrmedia.ua/RadioROKS_HD") = 49
Закоментировав  данный участок кода
Программа стала работать без сбоев, полет нормальный с 15.02.2021.

Есть загрузка в другие листбоксы, где  len  =  46 и сбой не возникает, изменив на большую длину текста до 50 символов, тоже возникает сбой,  свойства контролов стандартные, ограничений на длину текста нет.

Смущает факт того, что сбой возникает, только когда проект закрыт паролем для просмотра и редактирования, при удалении защиты все работает.
Если честно, я не понимаю взаимосвязи возникающей ошибки и защиты с паролированием проекта, но возможно, кто-то из гуру форума подскажет в чем кроется данная ошибка.
Power Query извлечь данные СSS HTML
 
Цитата
PooHkrd написал:
TSN , на этом сайте нечего парсить.
Парсинг – это автоматизированный процесс извлечения данных с веб-сайта. Так, что любой метод извлечения данных можно назвать парсингом.
Цитата
PooHkrd написал:
Вот если парсить то это примерно  по такому сценарию . Там да - бывает не просто.
Необязательно по такому.
Вот пример решения без использования jQuery, Power Query, по сценарию который я предложил изначально.
(извлечь данные по облачности и осадкам (не картинки), также извлечь направление ветра)
Если для ТС приемлемо такое решение пусть пользуется.
Код
Option Explicit
Option Compare Text
''' объект objHTMLDoc As HTMLDocument, объявлен ранним связыванием
''' Tools -> References -> Microsoft HTML Object Library. > C:\Windows\SysWOW64\mshtml.tlb
''' Для примера страница сайта с которой берем данные
Private Const strURL As String = " https://meteoinfo.ru/forecasts/russia/vologda-area/vologda"
 
Sub Parser_meteoinfo1 ()
Dim objHTMLDoc As HTMLDocument
Dim objXML As Object, Tag1, vl1, vl2
Dim strOtvetAukcion As String, strTrimer As String
Dim arr(), i As Long, x As Long

Set objHTMLDoc = New HTMLDocument
Set objXML = CreateObject("MSXML2.XMLHTTP.6.0")
objXML.Open "GET", strURL, False
objXML.setRequestHeader "Accept", "*/*"
objXML.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/58.0.1"
objXML.setRequestHeader "Proxy-Connection", "Keep-Alive"
objXML.setRequestHeader "Cache-Control", "no-cache"
objXML.setRequestHeader "If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 UTC"
objXML.setRequestHeader "Content-Type", "text/xml"
objXML.sEnd
While objXML.readyState <> 4: DoEvents: Wend
objHTMLDoc.body.innerHTML = objXML.responseText

''' набор данных
Set Tag1 = objHTMLDoc.getElementsByTagName("tr")
ReDim arr(1 To Tag1.Length, 1 To 2)
arr(1, 1) = "Осадки, день"
arr(1, 2) = "Ветер, м/с"

For Each vl1 In Tag1
  If vl1.innerHTML Like "*fc_small_gorizont_ww*" Then
    If vl1.innerHTML Like "*День*" Then
    ' извлечь данные по облачности и осадкам
      i = 1: x = 1
      For Each vl2 In vl1.Cells
        If vl2.innerText <> "День" Then
          i = i + 1
          arr(i, x) = vl2.Children.Item(0).Children.Item(0).Title
        End If
      Next
    End If
    If vl1.innerHTML Like "*Ветер, м/с*" Then
    ' извлечь направление ветра, скорость
      i = 1: x = 2
      For Each vl2 In vl1.Cells
        If vl2.innerText <> "Ветер, м/с" Then
          i = i + 1
          arr(i, x) = vl2.Children.Item(0).Children.Item(0).Title & ", " & vl2.innerText
        End If
      Next
    End If
  End If
  If x = 2 Then Exit For
Next
'' Поместить результат запроса на лист
ThisWorkbook.Sheets(1).Range("A1").Resize(UBound(arr, 1), UBound(arr, 2)) = arr

Set objHTMLDoc = Nothing
Set objXML = Nothing
End Sub

Скучно на работе, решил допилить добавив выгрузку и за ночное время в отдельные поля, в файле только первый вариант.

Код
Option Explicit
Option Compare Text
''' объект objHTMLDoc As HTMLDocument, объявлен ранним связыванием
''' Tools -> References -> Microsoft HTML Object Library. > C:\Windows\SysWOW64\mshtml.tlb

Sub Parser_meteoinfo()
Dim objHTMLDoc As HTMLDocument
Dim objXML As Object, Tag1, vl1, vl2
Dim strOtvetAukcion As String, strTrimer As String
Dim arr(), i As Long, x As Long

''' страница сайта с которой берем данные
Dim strURL As String
strURL = "https://meteoinfo.ru/forecasts/russia/vologda-area/vologda"

Set objHTMLDoc = New HTMLDocument
Set objXML = CreateObject("MSXML2.XMLHTTP.6.0")
objXML.Open "GET", strURL, False
objXML.setRequestHeader "Accept", "*/*"
objXML.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/58.0.1"
objXML.setRequestHeader "Proxy-Connection", "Keep-Alive"
objXML.setRequestHeader "Cache-Control", "no-cache"
objXML.setRequestHeader "If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 UTC"
objXML.setRequestHeader "Content-Type", "text/xml"
objXML.sEnd
While objXML.readyState <> 4: DoEvents: Wend
objHTMLDoc.body.innerHTML = objXML.responseText

''' набор данных
Set Tag1 = objHTMLDoc.getElementsByTagName("tr")
ReDim arr(1 To Tag1.Length, 1 To 4)
arr(1, 1) = "Осадки, день"
arr(1, 2) = "Ветер, м/с"
arr(1, 3) = "Осадки, ночь"
arr(1, 4) = "Ветер, м/с"

For Each vl1 In Tag1
  If vl1.innerHTML Like "*fc_small_gorizont_ww*" Then
    Debug.Print vbNewLine
    Debug.Print vl1.innerHTML
    If vl1.innerHTML Like "*День*" Then
    ' извлечь данные по облачности и осадкам
      i = 1: x = 1
      For Each vl2 In vl1.Cells
        If vl2.innerText <> "День" Then
          i = i + 1
          arr(i, x) = vl2.Children.Item(0).Children.Item(0).Title
        End If
      Next
    End If
    If vl1.innerHTML Like "*Ветер, м/с*" And _
    Not vl1.innerHTML Like "*fc_small_gorizont_ww sdvig_div*" Then
    ' извлечь направление ветра, скорость
      i = 1: x = 2
      For Each vl2 In vl1.Cells
        If vl2.innerText <> "Ветер, м/с" Then
          i = i + 1
          arr(i, x) = vl2.Children.Item(0).Children.Item(0).Title & ", " & vl2.innerText
        End If
      Next
    End If
    
    If vl1.innerHTML Like "*Ночь*" Then
    ' извлечь данные по облачности и осадкам за ночь
      i = 1: x = 3
      For Each vl2 In vl1.Cells
        If vl2.innerHTML Like "*fc_small_gorizont_ww sdvig_div*" Then
          i = i + 1
          arr(i, x) = vl2.Children.Item(0).Children.Item(0).Title
        End If
      Next
    End If
    If vl1.innerHTML Like "*Ветер, м/с*" And _
       vl1.innerHTML Like "*fc_small_gorizont_ww sdvig_div*" Then
    ' извлечь направление ветра, скорость за ночь
      i = 1: x = 4
      For Each vl2 In vl1.Cells
        If vl2.innerHTML Like "*fc_small_gorizont_ww sdvig_div*" Then
          i = i + 1
          arr(i, x) = vl2.Children.Item(0).Children.Item(0).Title & ", " & vl2.innerText
        End If
      Next
    End If
  End If
  If x = 4 Then Exit For
Next
'' Поместить результат запроса на лист
ThisWorkbook.Sheets(1).Range("A1").Resize(UBound(arr, 1), UBound(arr, 2)) = arr

Set objHTMLDoc = Nothing
Set objXML = Nothing
End Sub





Изменено: TSN - 18.02.2021 16:15:23
Power Query извлечь данные СSS HTML
 
Цитата
Power Query вам не поможет
Возможно я поспешил с выводом по поводу Power Query. Но эту технологию точно придется изучать, если есть желание ее использовать/
Последняя версия Power BI Desktop вышла с новым веб-соединителем, специально разработанным для сценариев веб-парсинга.
Power Query извлечь данные СSS HTML
 
Power Query вам не поможет
СSS  не хранит данные, это каскадные страницы стилей вебстраниц, описывают внешний вид кнопок, форм и т.д.

для обработки данных с Веб вам пожет парсинг
вариант 1. изучить  MSXML2.XMLHTTP.6.0 в паре с HTMLDocument
вариант 2. изучить InternetExplorer.Application - легче в освоении
для первичного ознакомления
Это все требует знания VBA.
Изменено: TSN - 16.02.2021 16:57:44
Выбрать из колонки А все, чего нет в колонке В, и положить в колонку С
 
Вот пример решения Вашей задачи, написал в рамках того как понял
Код
Sub RemovingDuplicates()
Dim OSD As Object, arr(), oRng
Dim i As Long, sTemp As String, tmp
Dim iLastRow As Long

' Вариант 1
' Создаем словарь со списка Что удалить исключая уникальнst
Set OSD = CreateObject("Scripting.Dictionary")
    OSD.comparemode = 1
With ThisWorkbook
  With Sheets("Лист1")
    ' Загрузка в одномерный массив данных со списка "Что удалить"
    arr = .Range(.Cells(2, 2), .Cells(Rows.Count, 2).End(xlUp)).Value
    ' Перегружаем в словарь для исключения повторений
    For i = LBound(arr) To UBound(arr)
      If Not OSD.exists(arr(i, 1)) Then OSD.Add CStr(arr(i, 1)), 0
    Next
    ' Выполняем анализ списка "Полный список", помечаем на удаление желтым фоном
    Set oRng = .Range(.Cells(2, 1), .Cells(Rows.Count, 1).End(xlUp))
    For Each tmp In oRng
      sTemp = tmp
      If OSD.exists(sTemp) Then tmp.Interior.Color = 65535
    Next
    ' Далее можно в ручном режиме выполнить фильтр по фону и удалить ненужные строки
    ' Можно процесс полностью автоматизировать,
    ' но для этого необходимо понимать полностью цели, задачи и т.д.
  End With
End With
Erase arr
Set oRng = Nothing
Set OSD = Nothing
End Sub
Вставьте этот код в стандартный модуль, почему то файл с примером не загружается на сайт.

Приношу свои извинения за невнимательность.
Вот  процедура с учетом желаний ТС с первого поста, просто полностью замените ее в файле с примером. Sub RemovingDuplicates()
Код
Sub RemovingDuplicates()
Dim OSD As Object, arr(), oRng
Dim i As Long, sTemp As String, tmp
Dim objItog As Object

' Вариант 2
' Создаем словарь со списка Что удалить
Set OSD = CreateObject("Scripting.Dictionary")
    OSD.comparemode = 1
' Создаем словарь Ответ
Set objItog = CreateObject("Scripting.Dictionary")
    objItog.comparemode = 1
With ThisWorkbook
  With Sheets("Лист1")
    ' Загрузка в одномерный массив данных со списка "Что удалить"
    arr = .Range(.Cells(2, 2), .Cells(Rows.Count, 2).End(xlUp)).Value
    ' Перегружаем в словарь для исключения повторений
    For i = LBound(arr) To UBound(arr)
      If Not OSD.exists(arr(i, 1)) Then OSD.Add CStr(arr(i, 1)), 0
    Next
    i = 2
    ' Выполняем анализ списка "Полный список"
    Set oRng = .Range(.Cells(2, 1), .Cells(Rows.Count, 1).End(xlUp))
    For Each tmp In oRng
      sTemp = tmp
      If OSD.exists(sTemp) Then
          ' Помечаем на удаление желтым фоном дубликаты
          tmp.Interior.Color = 65535
      Else
          ' Выгружаем ответ в столбец C начиная с ячейки C2 с проверкой на уникальность.
'          If Not objItog.exists(sTemp) Then objItog.Add CStr(sTemp), 0: .Cells(i, 3).Value = sTemp
          ' Выгружаем ответ в столбец C начиная с ячейки C2.
          .Cells(i, 3).Value = sTemp
          i = i + 1
      End If
    Next
  End With
End With
Erase arr
Set oRng = Nothing
Set OSD = Nothing
Set objItog = Nothing
End Sub
Изменено: TSN - 16.02.2021 11:13:24
Макрос для очистки от невидимого мусора в ячейках
 
Цитата
Marat Ta написал:
Отдал на заполнение, вернули размером в 20 мб
Разносили данные девушки, которые Excel на начальном уровне владеют.
Похоже Ваши девушки владеют не начальным уровнем, это как надо умудрится заполняя таблицу данными, напихать в файл кучу графических объектов.
Ваши девушки диверсанты :)
Макрос для очистки от невидимого мусора в ячейках
 
Цитата
Marat Ta написал:
К тому же убирает все форматы и оформления ячеек.
sht.Cells.ClearFormats - эта часть кода убирает все форматы и оформления ячеек.
Быстрый макрос вместо ВПР
 
Цитата
sinks написал:
Только вот в этой части кода я не смог переделать Range, чтобы диапазон сам считался. Вылетает окошко про дубликаты. Не могли бы вы мне помочь?
Ошибка в цикле. вот так будет Верно. Но есть один значительный минус, при таком подходе процедура завершится обнаружив первый дубликат в словаре и не сможет пройти весь диаппазон. Возможно Вам это и надо.
Код
arr = Range("A1:A9481").Value   ' получаем массив "ГДЕ ищем" из диапазона   
    For r = 1 To UBound(arr, 1) ' наполняем словарь из массива
        If dic.Exists(arr(r, 1)) Then MsgBox "The Value «" & x & "» have DUPLICATES!", vbCritical, "CLONES": Exit Sub
        dic.Add arr(r, 1), r    ' добавляем в словарь пару "значение - номер в массиве"
    Next r
Если нужен полный цикл измените на такую версию, позволяет пройти весь диаппазон Range искалючив дубликаты.
Код
arr = Range("A1:A9481").Value        ' получаем массив "ГДЕ ищем" из диапазона   
For r = 1 To UBound(arr, 1)          ' наполняем словарь из массива
  If not dic.Exists(arr(r, 1)) Then  ' исключаем дубликаты
     dic.Add Key:=arr(r, 1), Item:=r            ' добавляем в словарь пару "значение - номер в массиве"
  end if
Next r
Изменено: TSN - 15.02.2021 11:33:38
Макрос для очистки от невидимого мусора в ячейках
 
1. Возможно в файле имеются связи с другими книгами или файлами, что может влиять на быстродействие и размер
Посмотреть можно
Вкладка Данный >> Подключения > Изменить связи

2. Также могут быть в большом количестве именованные диапазоны, имена
Код
'' Поиск, удаление имен в файле
Sub delNames()
Dim nms
  With ThisWorkbook
    For Each nms In .Names
        Debug.Print nms; Space(3); nms.Name
        nms.Delete
    Next
  End With
End Sub

3. Также возможно поможет
Код
'' Очистка страниц книги
Sub ClearSheets()
Dim sht
  With ThisWorkbook
    For Each sht In .Sheets
     Debug.Print sht.Name
     sht.Cells.ClearComments
     sht.Cells.ClearFormats
     sht.Cells.ClearHyperlinks
     sht.Cells.ClearNotes
     sht.Cells.ClearOutline
    Next
  End With
End Sub
Изменено: TSN - 15.02.2021 11:15:53
При загрузке программы, Ексель уходит в ошибку., Прекращена работа программы Microsoft Excel
 
Цитата
Дмитрий(The_Prist) Щербаков написал:
Если объявляете через PtrSafe, то LonlLong лишнее - надо везде объявлять как LongPtr
Спасибо, сейчас исправлю. Я запутался с этими декларациями WinApi
При загрузке программы, Ексель уходит в ошибку., Прекращена работа программы Microsoft Excel
 
Цитата
Игорь написал:
одна из WinAPI функций объявлена неверно
Можете сказать правильно продекларированы WinAPI
Код
#If VBA7 Then
  #If Win64 Then '' Windows x64, Office 2010 - 2013 и выше
    '''API получить координаты ячейки экселя на экране компьютера
    Public Declare PtrSafe Function GetSystemMetrics Lib "user32" (ByVal nIndex As LongPtr) As LongPtr
    '''тайм аут
    Public Declare PtrSafe Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As LongPtr)
    '***** Работа с Clipboard Виндовс --- ClearClipboardApi
    Public Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hwnd As LongPtr) As LongPtr
    Public Declare PtrSafe Function EmptyClipboard Lib "user32" () As LongPtr
    Public Declare PtrSafe Function CloseClipboard Lib "user32" () As LongPtr
    '*****Для скрытого запуска документов (проверка орфографии) CheckSpellingText
    Public Declare PtrSafe Function CoAllowSetForegroundWindow Lib "ole32.dll" (ByVal pUnk As Object, ByVal lpvReserved As LongPtr) As LongPtr
    '***** Переключение раскладки на украинскую если в данный момент раскладка английская или русская
    Public Declare PtrSafe Function GetKeyboardLayoutName Lib "user32" Alias "GetKeyboardLayoutNameA" (ByVal pwszKLID As String) As LongPtr
    Public Declare PtrSafe Function ActivateKeyboardLayout Lib "user32" (ByVal HKL As LongPtr, ByVal flags As LongPtr) As LongPtr
    '' Декларируем для Всех Форм кнопки Свернуть Развернуть ---- Константы остались в формах
    Public Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongLong
    Public Declare PtrSafe Function ShowWindow Lib "user32" (ByVal hwnd As LongPtr, ByVal nCmdShow As LongLong) As LongLong 'для отображения окон
    Public Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As LongPtr) As LongLong
    Public Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As LongPtr, ByVal dwNewLong As LongLong) As LongLong
    Public Declare PtrSafe Function SetFocus Lib "user32" (ByVal hwnd As LongPtr) As LongPtr
    '' Продублирована часть функций из класса clsFormChanger
'    Public Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As LongPtr, ByVal hWnd2 As LongPtr, _
                                                                                     ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr
'    Public Declare PtrSafe Function DrawMenuBar Lib "user32" (ByVal hwnd As LongPtr) As LongPtr
'    Public Declare PtrSafe Function GetSystemMenu Lib "user32" (ByVal hwnd As LongPtr, ByVal bRevert As LongLong) As LongLong
'    Public Declare PtrSafe Function DeleteMenu Lib "user32" (ByVal hMenu As LongLong, ByVal nPosition As LongLong, ByVal wFlags As LongLong) As LongLong
'    Public Declare PtrSafe Function EnableWindow Lib "user32" (ByVal hwnd As LongPtr, ByVal fEnable As LongLong) As LongLong
'    Public Declare PtrSafe Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA" (ByVal hInst As LongLong, ByVal lpszExeFileName As String, ByVal nIconIndex As LongLong) As LongLong
'    Public Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As LongPtr, ByVal wMsg As LongLong, ByVal wParam As Integer, ByVal lParam As LongLong) As LongLong
'    Public Declare PtrSafe Function LockWindowUpdate Lib "user32" (ByVal hWndLock As LongPtr) As LongPtr
    '' Сделать ексель  прозрачным во время работы с формой (быстро или постепенно)
  ' Public Declare Function GetWindowLong Lib "USER32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As LongPtr) As LongPtr
  ' Public Declare Function SetWindowLong Lib "USER32" Alias "SetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As LongPtr, ByVal dwNewLong As LongPtr) As LongPtr
    Public Declare PtrSafe Function SetLayeredWindowAttributes Lib "user32" (ByVal hwnd As LongPtr, ByVal crKey As LongPtr, ByVal bAlpha As Byte, ByVal dwFlags As LongPtr) As LongPtr
    '' Отображения формы поверх всех окон:
    Public Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
    Public Declare PtrSafe Function SetWindowPos Lib "user32" (ByVal hwnd As LongPtr, ByVal hWndInsertAfter As LongPtr, _
                                                                ByVal x As LongPtr, ByVal y As LongPtr, ByVal cx As LongPtr, _
                                                                ByVal cy As LongPtr, ByVal wFlags As LongPtr) As LongPtr
 #Else '' Windows x86, Office 2010 - 2013 и выше
    '''API получить координаты ячейки экселя на экране компьютера
    Public Declare PtrSafe Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As LongPtr
    '''тайм аут
    Public Declare PtrSafe Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
    '***** Работа с Clipboard Виндовс --- ClearClipboardApi
    Public Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As LongPtr
    Public Declare PtrSafe Function EmptyClipboard Lib "user32" () As LongPtr
    Public Declare PtrSafe Function CloseClipboard Lib "user32" () As LongPtr
    '*****Для скрытого запуска документов (проверка орфографии) CheckSpellingText
    Public Declare PtrSafe Function CoAllowSetForegroundWindow Lib "ole32.dll" (ByVal pUnk As Object, ByVal lpvReserved As LongPtr) As LongPtr
    '***** Переключение раскладки на украинскую если в данный момент раскладка английская или русская
    Public Declare PtrSafe Function GetKeyboardLayoutName Lib "user32" Alias "GetKeyboardLayoutNameA" (ByVal pwszKLID As String) As LongPtr
    Public Declare PtrSafe Function ActivateKeyboardLayout Lib "user32" (ByVal HKL As LongPtr, ByVal flags As LongPtr) As LongPtr
    '' Декларируем для Всех Форм кнопки Свернуть Развернуть ---- Константы остались в формах
    Public Declare PtrSafe Function SetFocus Lib "user32" (ByVal hwnd As Long) As Long
    Public Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
    Public Declare PtrSafe Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As LongPtr) As LongPtr 'для отображения окон
    Public Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As LongPtr
    Public Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
    '' Продублирована часть функций из класса clsFormChanger
'    Public Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As LongPtr, ByVal hWnd2 As LongPtr, _
                                                                                     ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr
'    Public Declare PtrSafe Function DrawMenuBar Lib "user32" (ByVal hwnd As Long) As LongPtr
'    Public Declare PtrSafe Function GetSystemMenu Lib "user32" (ByVal hwnd As Long, ByVal bRevert As LongPtr) As LongPtr
'    Public Declare PtrSafe Function DeleteMenu Lib "user32" (ByVal hMenu As LongPtr, ByVal nPosition As LongPtr, ByVal wFlags As LongPtr) As LongPtr
'    Public Declare PtrSafe Function EnableWindow Lib "user32" (ByVal hwnd As Long, ByVal fEnable As LongPtr) As LongPtr
'    Public Declare PtrSafe Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA" (ByVal hInst As LongPtr, ByVal lpszExeFileName As String, ByVal nIconIndex As LongPtr) As LongPtr
'    Public Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As LongPtr, ByVal wParam As Integer, ByVal lParam As LongPtr) As LongPtr
'    Public Declare PtrSafe Function LockWindowUpdate Lib "user32" (ByVal hWndLock As LongPtr) As LongPtr
      '' Сделать ексель  прозрачным во время работы с формой (быстро или постепенно)
  ' Public Declare Function GetWindowLong Lib "USER32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
  ' Public Declare Function SetWindowLong Lib "USER32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Public Declare PtrSafe Function SetLayeredWindowAttributes Lib "user32" (ByVal hwnd As Long, ByVal crKey As LongPtr, ByVal bAlpha As Byte, ByVal dwFlags As LongPtr) As LongPtr
    Public Declare PtrSafe Function GetActiveWindow Lib "user32" () As Long
    Public Declare PtrSafe Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As LongPtr, _
                                                                ByVal x As LongPtr, ByVal y As LongPtr, ByVal cx As LongPtr, _
                                                                ByVal cy As LongPtr, ByVal wFlags As LongPtr) As LongPtr
  #End If
#Else 
При загрузке программы, Ексель уходит в ошибку., Прекращена работа программы Microsoft Excel
 
Уважаемые форумчане, прошу помощи!
В файле Excel разработал программу. В ней большая UserForm, много процедур.
Работало все прекрасно, последние две недели при загрузке программы, Ексель уходит в ошибку.
Если запускать программу пошагово [F8], загрузка выполняется без проблем.
Исследуя код в поисках возможной ошибки обратил внимание, что все записи (во  всех процедурах) со значением .Value  изменены на .value редактор VBA сам приводит их к такому формату.
Выложить файл не могу, он более 2 Мбайт весом.

Версия Windows  7 х64, Excel 2010.В программе используются функции API декларированные  
#If VBA7 Then
       #If Win64 Then #Else #End If
#Else
#End If
Также ссылки на библиотеки:
VBA|Visual Basic For Applications (VBE7.DLL); Excel|Microsoft Excel 14.0 Object Library; stdole|OLE Automation; Office|Microsoft Office 14.0 Object Library; MSForms|Microsoft Forms 2.0 Object Library; Word|Microsoft Word 14.0 Object Library; ADODB|Microsoft ActiveX Data Objects 6.0 Library; VBIDE|Microsoft Visual Basic for Applications Extensibility 5.3 (\VBE6EXT.OLB); MSHTML|Microsoft HTML Object Library; MSScriptControl|Microsoft Script Control 1.0

Подскажите, что произошло с программой, почему редактор VBA меняет код  .value  ?
Изменено: TSN - 30.11.2020 10:25:45
Проблема с запросом XMLHTTPRequest, не возвращает корректные данные с сайта
 
Спасибо doober, я знал, что на форуме есть добрые люди.
Я так понял, что мне нужно изменить строку запроса
с https://auction.openprocurement.org/tenders/2889f213faf9415ba9d27e97fd675cd9
на https://auction.openprocurement.org/database/2889f213faf9415ba9d27e97fd675cd9
что не является проблемой.
Также изучить как обработать ответ JSON

Я так понял, что эта запись на странице
<script type=text/javascript>
var db_url = location.protocol + '//' + location.host + '/database';
var auction_doc_id = '';
говорит о том что перенаправляется запрос к базе данных.
Изменено: TSN - 22.10.2020 10:04:32
Проблема с запросом XMLHTTPRequest, не возвращает корректные данные с сайта
 
Добрый день уважаемые форумчане, помогите решить задачу.
Есть программа которая занимается парсингом нескольких сайтов, в целом выполняется 15 различных процедур. Парсинг построен на объекте InternetExplorer.Application На протяжении нескольких лет все работает, но есть некоторые проблемы с IE (в отделе несколько компов с разными версиями Windows и Ексель приходится лепить различные костыли для нормальной работы с IE, также не устраивает скорость выполнения парсинга некоторых сайтов).
Решил перейти на объект MSXML2.XMLHTTP, в целом все прошло успешно, 14 процедур работают отлично, скорость парсинга повысилась в разы.
Парсинг одной процедуры не возвращает корректные данные.
Вместо:
ТОВ "Наименование 1" 148 000,00 грн
ТОВ "Наименование 2" 163 440,00 грн
Выдает:
Initial bids Bidders
{{ bid_info.label[lang]||"-" }} You Normilized Price {{ bid_info['amount_features']|fraction }}

InternetExplorer до сегодняшнего дня возвращал корректные данные, сегодня тоже перестал.
Исследуя страницу в браузере обратил внимание, что появился новый тег <span, раньше его не было возможно в нем причина.
Перепробовал различные варианты запросов к странице, безрезультатно.
Помогите найти решение как получить нормальный ответ.

Пример кода
Код
Option Explicit
Option Compare Text

''' Для примера страница сайта с которой есть проблема XML
Private Const strURL As String = "https://auction.openprocurement.org/tenders/2889f213faf9415ba9d27e97fd675cd9"

Sub NotWorkingParser_XML()
Dim objHTMLDoc As HTMLDocument
''' объект objHTMLDoc As HTMLDocument, объявлен ранним связыванием
''' Tools -> References -> Microsoft HTML Object Library. > C:\Windows\SysWOW64\mshtml.tlb
Dim objXML As Object, Tag1, vl1
Dim strOtvetAukcion As String, strTrimer As String

Set objHTMLDoc = New HTMLDocument
Set objXML = CreateObject("MSXML2.XMLHTTP.6.0")
''' Формирование заголовка запроса
objXML.Open "GET", strURL, False
objXML.setRequestHeader "Accept", "*/*"
objXML.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/58.0.1"
objXML.setRequestHeader "Proxy-Connection", "Keep-Alive"
objXML.setRequestHeader "Cache-Control", "no-cache"
objXML.setRequestHeader "If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 UTC"
objXML.setRequestHeader "Content-Type", "text/xml"
'''Чтобы браузер распарсил ответ сервера в свойство responseXML, _
   в ответе должен быть заголовок Content-Type: text/xml. Иначе свойство responseXML будет равно null.
'''objXML.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
objXML.sEnd
''' Получить ответ
While objXML.readyState <> 4: DoEvents: Wend
objHTMLDoc.body.innerHTML = objXML.responseText

''' ===========================================
''' В процессе реализации получить ответ использовались различные методы
''' getElementById, getElementsByClassName, getElementsByTagName
''' setRequestHeader "Content-Type", "text/xml", "application/x-www-form-urlencoded", "text/html"
''' objHTMLDoc.body.innerHTML = ConvertBytesToString(objXML.responseBody)
''' ничего не помогло (:
''' ===========================================

''' статус аукциона
Set Tag1 = objHTMLDoc.getElementsByClassName("header-auction-item navbar-brand pull-left round-info timer-text")
Debug.Print Trim$(Tag1.Item(0).innerText) & vbNewLine
''' набор данных шаги аукциона
For Each Tag1 In objHTMLDoc.getElementsByClassName("auction-round")
  For Each vl1 In Tag1.Children
    strTrimer = Trim$(Application.WorksheetFunction.Clean(vl1.innerText))
    strOtvetAukcion = strOtvetAukcion & strTrimer & vbNewLine
  Next
  Debug.Print strOtvetAukcion & vbNewLine
  strOtvetAukcion = vbNullString
Next
Set objHTMLDoc = Nothing
Set objXML = Nothing
End Sub
      
Sub NotWorkingParser_IE()
''' Минусы работы с InternetExplorer
''' 1. Проблемы возникают при наличии в отделе нескольких компов с разными версиями Windows, IE
''' 2. Скорость выполнения парсинга сайтов. По сравнению с XML иногда достигает разницы в десятки раз.
Dim objIE As Object
Dim strOtvetAukcion As String, strTrimer As String
Dim Tag1, vl1
    Set objIE = CreateObject("InternetExplorer.Application"):
    objIE.navigate strURL
    DoEvents
    While objIE.busy Or (objIE.readyState <> 4): DoEvents: Wend
'    Do While objIE.busy Or (objIE.readyState <> 4)
'      DoEvents: Application.Wait (Now + TimeValue("0:00:02"))
'    Loop
    ''' статус аукциона
    Set Tag1 = objIE.document.getElementsByClassName("header-auction-item navbar-brand pull-left round-info timer-text")
    Debug.Print Trim$(Tag1.Item(0).innerText)
    ''' набор данных шаги аукциона
    For Each Tag1 In objIE.document.getElementsByClassName("auction-round")
      For Each vl1 In Tag1.Children
        strTrimer = Trim$(Application.WorksheetFunction.Clean(vl1.innerText))
        strOtvetAukcion = strOtvetAukcion & strTrimer & vbNewLine
      Next
      ''' ответ веб-страницы
      Debug.Print strOtvetAukcion
      strOtvetAukcion = vbNullString
    Next
objIE.Quit: Set objIE = Nothing
End Sub
        
Private Function ConvertBytesToString(ArrByte)
Dim ADOStream
Set ADOStream = CreateObject("ADODB.Stream")
  With ADOStream
    .Type = 1 'adTypeBinary
    .Open:  .Write ArrByte: .Position = 0
    .Type = 2 'adTypeText
    .Charset = "windows-1251"
     ConvertBytesToString = .ReadText
    .Close
  End With
Set ADOStream = Nothing
End Function

Автоматическое обновление ссылок Excel 2010 - не работает у части пользователей
 
Anastasia111, Посмотрите настройки Ексель на всех компьтерах.
Параметры > Центр управления безопасностью > Внешнее содержимое > Параметры безопасности для связей в книге и Пармаметры безопасности для подключения к данным.
Возможно это решит вашу проблему.
Зачитать и сохранить плейлисты
 
Цитата
Acid Burn написал:
1. Теперь всё непонятое макросом будет улавливаться в соответствующий столбец?Или, если структура будет совсем иная/кривая, что-то всё же может быть пропущено?
Да если структура будет совсем иная/кривая, что-то может быть пропущено. Я алгоритм анализа писал на основании данных  с файлов примеров. Структура файлов m3u похожа на структуру Xml, возможно применив XML DOM проще и без ошибок можно парсить m3u файлы. Мои познания в XML DOM слабоваты поэтому не применял его.
Цитата
Acid Burn написал:
- изменить имена листов (сейчас в обоих файлах листы названы ASX*)
Не заметил сорян, это просто изменить.

Цитата
Acid Burn написал:
перетащить инфо из столбца H в столбец C, если тот не заполнен
Изначально в третей версии так и сделал, потом убрал решив, что будет лишним :)
Цитата
Acid Burn написал:
сделать ссылки кликабельными или обернуть в функцию =ГИПЕРССЫЛКА("Ссылка";"Сервер")
а функцию ГИПЕРССЫЛКА и вовсе вряд ли можно применить из-за осложнения поиска дубликатов.
Гиперссылки сделать просто при условии формирования нового файла в момент удаления дубликатов.
Для процедур (кнопки) Update file, RemoveDuplicates нужно переписывать алгоритм поиска дубликатов с учетом наличия гиперссылок.

В целом все это мелочи, еще оскому не сбил в программировании на VBA, допилю и выложу обновленную версию.
Зачитать и сохранить плейлисты
 
Цитата
Acid Burn написал:
На счёт столбца "Не классифицировано":посмотрите в Mult.m3u8 ссылку  https://strm.yandex.ru/vh-ott-converted/ott-content/328514357 Parser потерял кусок ", но боялись спросить...".Вот такие куски я и хотел бы видеть в "Не классифицировано", чтобы вручную разобрать и перенести на место.
Когда писал первый вариант не заметил, что  строки файлов м3u различаются
Это основная структура записи
#EXTINF:-1 group-title="Герои Энвелла",Сезон 1 - Серия 10 - Неизвестная локация
https: //strm.yandex.ru/vh-ott-converted/ott-content/493306269-41178fc958d098058dda2b906148c594/master_quality.m3u8
В приведенном примере Вами другая
Алгоритм анализа фалов m3u переписал, работает корректно.
Цитата
Acid Burn написал:
Вместо выбора папки лучше вернуть выбор файлов с strMyDocuments = Application.ActiveWorkbook.Path & "\".
Добавил две константы и реализацию диалогов. Это пример того как можно собрать с двух вариантов один.
'константа для выбора управления диалоговыми окнами выбора файла или папки
'0 - используется диалог выбора файлов, 1 - используется диалог выбора папки
Private Const SHOWUSERDIALOG As Byte = 0
'константа для выбора папки сохранения
'0 - сохраняет результатирующий файл по умолчанию в папку с Parserом, 1 - используется диалог выбора папки
Private Const SAVEDUSERPATH As Byte = 0
Меняйте значения этих констант и получите разную реализацию работы пользователя с диалоговыми окнами и путями сохранения файлов ответов.
По умолчанию работает с папкой в которой лежит программа.
Цитата
Acid Burn написал:
Все m3u и asx нужно собрать в одну таблицу в одном файле
m3u файлы собираются в одну таблицу  с удалением дубликатов (с тех файлов которые выбрал пользователь или тех которые лежат в одной папке), сохраняются в один файл ResultatM3U_дата_время. Asx файлы оставил в тойже реализации, собираются данные в отдельный файл ResultatASX_дата_время.  Asx файлов много, данных на выходе мало, и данные таких файлов отличаются от таблиц m3u файлов.
Цитата
Acid Burn написал:
на том листе, с которого запущен макрос.
Программа работает с внешними файлами, в себя ничего не загружает, реализованы диалоги обращения к внешним файлам.  Мое мнение вы знаете мухи отдельно, котлеты отдельно.
Цитата
Acid Burn написал:
- При повторном запуске макроса новые данные должны добавляться в ту же таблицу (если реально, то без дублей).- То, что "источник разный" не важно, пусть остаётся первый попавшийся - на выходе всё равно будет новый файл.
Написал процедуру парсинга файлов с возможностью дописать данные в существующий файл выбранный пользователем. Данные добавляются в имеющуюся таблицу в файле с удалением дубликатов.
Дополнительно написал процедуру удаления дубликатов данных в существующем файле ответе (ResultatM3U_дата_время. ) выбранном пользователем (вспомогательная процедура). Основное назначение при условии, что пользователь самостоятельно собрал с нескольких файлов ответов одну таблицу.

Пользуйтесь.
Изменено: TSN - 29.09.2020 10:02:06
Зачитать и сохранить плейлисты
 
vikttur, Извините, я давно не был на этом форуме, правила забыл, повторно не читал.
БМВ мне на счётчик наплевать, я благодарен этому форуму за знания в программировании в Vba, с этих страниц много лет назад началось моё обучение. Хотел бы накрутить счётчик, писал бы короткие фразы во всех постах не вникая в суть вопроса :).
Acid Burn, Ваш последний пост уже немного похож на тех задание, это как раз, то о чем писали учасники форума в постах выше, например пост 22. Я сделал ровно так как понял из текста в первом посте. В целом у вас есть два варианта программы выполняющей одну и ту же задачу, перепишите код на свое усмотрение, соберите с двух одно, добавте дополнительный анализ строк файлов. Я вам дал фундамент для решения задачи, дальше наращивайте по своему усмотрению. Я в свою очередь ушёл в сон, а завтра на море до понедельника. Если на следующей неделе будет время на работе тогда смогу доработать.
Цитата
- Все m3u и asx нужно собрать в одну таблицу в одном файле, на том листе, с которого запущен макрос.
Я не рекомендую в файл с програмным кодом загружать данные в таком большем объеме, в один прекрасный день произойдёт сбой и можно потерять программу и данные. Мухи отдельно, котлеты отдельно, это моё мнение.  
Изменено: TSN - 24.09.2020 21:52:17
Зачитать и сохранить плейлисты
 
Цитата
Acid Burn написал:
Закономерность - одинаковая ссылка на ресурс (названия и т.п. могут отличаться, но, если ссылка та же, то это точно дубль).
Закономерность не полноценная вот пример
ИсточникКатегорияНазваниеСсылка
Films.m3u8Не попали в категории   по годамentermusictvhttp ://v2.catcast.me/content/36007/index.m3u8
TV.m3u8Фильмовыеentermusictvhttp ://v2.catcast.me/content/36007/index.m3u8
Как видно из таблицы ссылка на ресурс одна, но источник разный. Какой источник должен остаться ?
А в целом да, дубликатов много, из данных файлов примеров 79952 ссылки из них уникальных 74360 шт.
Изменено: TSN - 24.09.2020 12:16:53
Зачитать и сохранить плейлисты
 
Цитата
Acid Burn написал:
Я имел ввиду заменить SpecialFolders("MyDocuments") на Application.ActiveWorkbook.Path.
У большенства пользователей папка мои документы является основной для использования, поэтому было принято решение использовать именно ее как папку по умолчанию, в коде последеней программы это всего одна строка, которую можно изменить под себя
Код
strMyDocuments = CreateObject("WScript.Shell").SpecialFolders("MyDocuments") & "\"
Изменив значение переменной strMyDocuments можно получить желаемое. Например так
Код
strMyDocuments = Application.ActiveWorkbook.Path & "\"
Изменено: TSN - 24.09.2020 11:56:50
Зачитать и сохранить плейлисты
 
Переписал часть кода, получился альтернативный вариант
Изменено:
1.  При запуске выбирается папка с файлами, вместо файлов.
2.  Все данные с файлов m3u собираются в одну таблицу в одном файле
Добавлено:
1.  Диалог с пользователем по выбору папки для сохранения файлов ответов, стартует сразу после диалога выбора папок с файлами.
2.  После анализа файлов ASX и формирования таблицы ответов файл сохраняется и закрывается.
Сохранение выполняется в указанную папку пользователем с  уникальным именем для исключения наложений и уничтожения предыдущих файлов.
3.  Во время анализа файлов m3u и формирования таблицы ответов файл сохраняется после каждой дозагрузки таблицы,  закрывается.
Сохранение выполняется в указанную папку пользователем с  уникальным именем для исключения наложений и уничтожения предыдущих файлов.
4.  Добавлено уведомление исполнения с возможностью отмены процедуры во время анализа файлов m3u.
5.  Добавлена стартовая кнопка в файле.

Пользуйтесь.
Зачитать и сохранить плейлисты
 
Цитата
Acid Burn написал:
Да, теперь столбец есть, но пока что пустой. )
Я так понимаю данный столбец для пользователя, чтобы вносить свои правки, замечания и т.д.
Зачитать и сохранить плейлисты
 
Как столбец сделать последним, я уже показал в примере, замена двух строк кода всего.
Я так понял неудобно выбирать файлы вместо папки.
Перепишу часть кода с возможностью выбора папки вместо файлов и сборкой ответа с файлов m3u в одну таблицу файла Ексель.
Удаление дубликатов по столбцу "Ссылка" под вопросом, если найду закономерность и будет время тогда реализую иначе нет.
Изменено: TSN - 24.09.2020 08:09:25
Зачитать и сохранить плейлисты
 
Цитата
Acid Burn написал:
не хватает столбца "Не классифицировано"
Я его не добавил, не обратил внимание когда читал тех задание. Это легко исправить, где он должен быть?.
Если предположить, что это последнее поле таблиц, тогда в
строке кода 142 заменить текст на ReDim arr(1 To (iMaxRow / 2) + 1, 1 To 8
дописать строку 146 (она сейчас пустая)   arr(i,8) = "Не классифицировано"
Код
' переопределение массива и формирование шапки
  ReDim arr(1 To (iMaxRow / 2) + 1, 1 To 8)
  i = 1
  arr(i, 1) = "Источник": arr(i, 2) = "Категория": arr(i, 3) = "Название"
  arr(i, 4) = "Ссылка":  arr(i, 5) = "Сервер":  arr(i, 6) = "Обложка":  arr(i, 7) = "Статус"
  arr(i, 8) = "Не классифицировано"


Я специально сделал так, чтобы каждый файл m3u8 собирался в отдельную книгу и таблицу. Данных много в обрабатываемом файле, если их собрать в одно целое сразу, будет тормозить выполнение процедуры, возможно с зависанием компа. В примерах файлы m3u8 по итогу выгружали таблицу на 10000 строк, если запустить анализ 100 файлов, таблица ответа будет 1000000 строк примерно, что очень тяжело для ексель. Хотя при желании можно сделать дозагрузку ответов в уже имеющуюся таблицу.
Изменено: TSN - 23.09.2020 15:40:42
Зачитать и сохранить плейлисты
 

Приветствую форумчане.

Давно меня здесь не было, 2 часа пароль вспоминал.

На мой взгляд интересная задачка, решил помочь ТС.

Не пинайте за код, давно не практиковался, решил поразмять мозг немного.

Комментариев к коду мало, только основные моменты, нет достаточного свободного времени.

Кнопку не прикрутил, думаю ТС сможет сам, если нет, то запуск процедуры Alt+F8 в помощь.

Процедура выполняет анализ файлов ASX и m3u8 согласно примера (загруженных файлов плейлисты), каждый проанализированный файл m3u8 выгружается в отдельную книгу EXCEL, файлы ASX собираются в одну таблицу в одной книге. Протестировано на работоспособность в Windows7, Excel 2010, должно работать и в остальных версиях, т.к. функции API не использовались, нестандартные функции не использовались.

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

Процедуры сборки обратно в файл m3u8 не написал.

Код
Код
Public Sub ParserASX_M3U()
'Основная процедура парсинга файлов ASX, m3u8
Dim i As Long, x As Long, n As Long
Dim tmp, temp
Dim arr1(), arr2()
Dim strTemp As String

' Получить коллекцию фалов для обработки.
' Используем внешнюю функцию диалог пользователя открыть файл, _
  дает возможность выбора (обработки) как одного так и всех файлов в папке.
Dim objFilesCollection As Collection
Set objFilesCollection = GetCollectionFilesDialog
If objFilesCollection.Count = 0 Then Exit Sub
' Перебор коллекции поиск фалов ASX и m3u
Dim objASXCollection As New Collection
Dim objM3UCollection As New Collection
For Each tmp In objFilesCollection
  If tmp Like "*.asx" Then
    objASXCollection.Add tmp
  ElseIf tmp Like "*.m3u*" Then
    objM3UCollection.Add tmp
  Else
  End If
Next tmp
Set objFilesCollection = Nothing

' Работаем с файлами ASX
' Считsваем данные файла внешней функцией
If objASXCollection.Count > 0 Then
  arr1 = GetCollectionASXfileText(objASXCollection)
  If LBound(arr1) > 0 Then
    arr1(1, 1) = "TITLE": arr1(1, 2) = "HREF"
    ' Выгружаем данные в новую книгу без сохранения
    Call CreateEXCELfile(arr1, "ASX files", 0)
  End If
End If
' Работаем с файлами m3u8
' Считsваем данные файла внешней функцией
If objM3UCollection.Count > 0 Then
  For Each tmp In objM3UCollection
    strTemp = CreateObject("Scripting.FileSystemObject").GetFileName(tmp)
    arr2 = GetCollectionM3UfileText(tmp)
    If LBound(arr2) > 0 Then
      ' Выгружаем данные в новую книгу без сохранения _
        для каждого файла создается отдельная новая книга
        Call CreateEXCELfile(arr2, strTemp, 1)
    End If
  Next
End If
Set objASXCollection = Nothing
Set objM3UCollection = Nothing
Erase arr1: Erase arr2
End Sub

Private Sub CreateEXCELfile(arrTemp, strNameSht As String, byteDataType As Byte)
''' ЗАГРУЖАЕМ ДАННЫЕ В СОЗДАННУЮ КНИГУ И РАБОТАЕМ С НЕЙ
' byteDataType - тип загружаемых данных (0 = массив файлов ASX, 1 = массив файлов m3u8)
Dim oExcelFile As Object
Dim iMaxRow As Long, iMaxClmn As Long
Dim i As Long, n As Long
iMaxRow = UBound(arrTemp, 1)
iMaxClmn = UBound(arrTemp, 2)

Workbooks.Add -4167 '=xlWBATWorksheet
''' Cоздаем новую книгу с одним листом
With CreateObject("Excel.Sheet"): Set oExcelFile = ActiveWorkbook: End With
With oExcelFile
  ActiveSheet.Name = strNameSht
  With .Sheets(strNameSht)
    ''' Формат ширин полей
    If byteDataType = 0 Then
      For Each oVl In .Range(.Cells(1, 1), .Cells(1, 1).Offset(, iMaxClmn - 1))
        Select Case oVl.Column
          Case Is = 1: oVl.ColumnWidth = 30: Case Is = 2: oVl.ColumnWidth = 145
        End Select
      Next
    ElseIf byteDataType = 1 Then
      For Each oVl In .Range(.Cells(1, 1), .Cells(1, 1).Offset(, iMaxClmn - 1))
        Select Case oVl.Column
          Case Is = 1: oVl.ColumnWidth = 15:  Case Is = 2: oVl.ColumnWidth = 25
          Case Is = 3: oVl.ColumnWidth = 45:  Case Is = 4: oVl.ColumnWidth = 45
          Case Is = 5: oVl.ColumnWidth = 25:  Case Is = 6: oVl.ColumnWidth = 25
          Case Is = 7: oVl.ColumnWidth = 15
        End Select
      Next
    Else
    End If
    ''' Выгружаем данные на лист
    .Range("A1").Resize(iMaxRow, iMaxClmn) = arrTemp '
    ''' Общее форматирование данных на листе
    ''' Форматируем шапку таблицы
    With .Range(.Cells(1, 1), .Cells(1, 1).Offset(, iMaxClmn - 1))
       .HorizontalAlignment = -4108 ' xlCenter
       .VerticalAlignment = -4108   ' xlCenter
       .Interior.Pattern = 1        ' xlSolid
       .Borders.LineStyle = 1       ' xlContinuous
       .Font.Bold = True            ' шрифт жирный
       .WrapText = True             ' перенос текста в ячейке
       .Interior.ColorIndex = 35
       .AutoFilter
    End With
    .Cells(2, 1).Select:  ActiveWindow.FreezePanes = True ''' Закрепить область на второй строке
    ''' Форматируем общие форматы таблицы
    With .Range(.Cells(2, 1), .Cells(iMaxRow, iMaxClmn))
        .HorizontalAlignment = -4131 'xlLeft
        .VerticalAlignment = -4108
        .Borders.LineStyle = 1
        .Interior.ColorIndex = -4105
        .WrapText = False
        .Font.Bold = False
        .Rows.AutoFit
        .Locked = True
    End With
  End With
End With
Erase arrTemp
End Sub

Private Function GetCollectionM3UfileText(strFileName) As Variant
' Функция обрабатывает содержимое файлов ASX возвращая массив
' Источник, Категория, Название, Ссылка, Сервер, Обложка, Статус
Dim oVl, iMaxRow As Long
Dim strLine1 As String, strLine2 As String
Dim arr(), arr1(0, 0), tmp, strTemp, strTemp1
Dim i As Long, n As Long

' Загрузка данных из файла в коллекции, считываем весь текс _
  Используется UTF8 для коррекктного чтения данных
  With CreateObject("ADODB.Stream")
    .Charset = "utf-8": .Mode = 3: .Type = 1
    .Open
    .LoadFromFile strFileName
    .Position = 0: .Type = 2
    strTemp = .ReadText
    oVl = Split(strTemp, vbCrLf)
    iMaxRow = UBound(oVl)
    .Close
    strTemp = vbNullString
  End With
  strFileName = CreateObject("Scripting.FileSystemObject").GetFileName(strFileName)
  ' переопределение массива и формирование шапки
  ReDim arr(1 To (iMaxRow / 2) + 1, 1 To 7)
  i = 1
  arr(i, 1) = "Источник": arr(i, 2) = "Категория": arr(i, 3) = "Название"
  arr(i, 4) = "Ссылка":  arr(i, 5) = "Сервер":  arr(i, 6) = "Обложка":  arr(i, 7) = "Статус"
    
  For n = 1 To iMaxRow Step 2
    If oVl(n) Like "*EXTINF*" Then
      i = i + 1
      strTemp = Split(oVl(n), ",", -1, 1)
      '"Источник"
      arr(i, 1) = strFileName
      '"Категория"
        strTemp(0) = Replace(strTemp(0), "#EXTINF:-1 group-title=", "", 1, -1, 1)
        strTemp(0) = Replace(strTemp(0), Chr(34), "", 1, -1, 1)
        
        If strTemp(0) Like "*tvg-logo*" Then
          strTemp1 = Split(strTemp(0), "tvg-logo=", -1, 1)
          arr(i, 2) = Trim(strTemp1(0))
          '"Обложка"
          arr(i, 6) = Trim(strTemp1(1))
        Else
          arr(i, 2) = Trim(strTemp(0))
          arr(i, 6) = "-"
        End If
      '"Название"
      If strTemp(1) Like "*===*" Then strTemp(1) = Replace(strTemp(1), "=", "", 1, -1, 1)
      arr(i, 3) = strTemp(1)
      ' "Ссылка"
      If oVl(n + 1) Like "*http*" Then arr(i, 4) = oVl(n + 1)
      ' "Сервер"
        strTemp = Split(oVl(n + 1), "/", -1, 1)
        arr(i, 5) = strTemp(2)
      
      ' "Статус"
      arr(i, 7) = "I don't know"
      
    End If
  Next n
Erase oVl: oVl = Empty
strFileName = vbNullString
If i > 0 Then GetCollectionM3UfileText = arr Else GetCollectionM3UfileText = arr1
Erase arr
End Function

Private Function GetCollectionASXfileText(objColl As Object) As Variant
' Функция обрабатывает содержимое файлов ASX возвращая массив
Dim strBuf As String, intFreeFile As Long, Lines() As String
Dim strLine1 As String, strLine2 As String
Dim arr(), arr1(0, 0), tmp, temp
Dim i As Long, n As Long
ReDim arr(1 To objColl.Count + 1, 1 To 2): n = 1
For Each tmp In objColl
  intFreeFile = FreeFile
  Open tmp For Binary As #intFreeFile
  strBuf = Space(LOF(intFreeFile))
  Get #intFreeFile, , strBuf
  Close #intFreeFile
  Lines = Split(strBuf, vbCrLf)
  strBuf = vbNullString
    For i = 0 To UBound(Lines)
      If Lines(i) Like "*<TITLE>*" Then
        Lines(i) = Replace(Lines(i), "<Entry>", "", 1, -1, vbTextCompare)
        Lines(i) = Replace(Lines(i), "<TITLE>", "", 1, -1, vbTextCompare)
        Lines(i) = Replace(Lines(i), "</TITLE>", "", 1, -1, vbTextCompare)
        Lines(i) = Trim(Lines(i))
        strLine1 = Lines(i)
      ElseIf Lines(i) Like "*<ref*" Then
        Lines(i) = Replace(Lines(i), "<ref HREF=", "", 1, -1, vbTextCompare)
        Lines(i) = Replace(Lines(i), "/>", "", 1, -1, vbTextCompare)
        Lines(i) = Replace(Lines(i), Chr(34), "", 1, -1, vbTextCompare)
        Lines(i) = Trim(Lines(i))
        strLine2 = Lines(i)
      Else
      End If
    Next i
    If Len(strLine1) > 0 And Len(strLine2) > 0 Then
      n = n + 1
      arr(n, 1) = strLine1: arr(n, 2) = strLine2
    End If
    strLine1 = vbNullString: strLine2 = vbNullString
Next
If i > 0 Then GetCollectionASXfileText = arr Else GetCollectionASXfileText = arr1
Erase arr
End Function

Private Function GetCollectionFilesDialog() As Collection
''' Функция диалога выбора файлов FileDialog(msoFileDialogFilePicker)
''' Возвращает коллекцию файлов выбраных пользователем
Dim objColl As New Collection
Dim intSelectFile As Long
Dim strMyDocuments
strMyDocuments = CreateObject("WScript.Shell").SpecialFolders("MyDocuments") & "\"
  With Application.FileDialog(3)
      .AllowMultiSelect = True
      .Title = "Выбрать файлы ASX, m3u8 для обработки"
      .Filters.Clear
      .Filters.Add "All files", "*.*", 1
      .Filters.Add "ASX files", "*.asx", 2
      .Filters.Add "m3u8 files", "*.m3u8", 3
      .FilterIndex = 3
      .InitialFileName = strMyDocuments & "*.*.*.*"
      .InitialView = 2
      If .Show = 0 Then
        Set GetCollectionFilesDialog = objColl
        Exit Function
      End If
      'цикл по коллекции выбранных в диалоге файлов, считываем полный путь к файлу
      For intSelectFile = 1 To .SelectedItems.Count
          objColl.Add .SelectedItems(intSelectFile)
      Next
      Set GetCollectionFilesDialog = objColl
  End With
End Function



Пользуйтесь.

Отпишите помогло или как ?

Изменено: TSN - 23.09.2020 14:58:16
Вставка текста из txt в ячейку
 
Цитата
valentinM написал:
Добрый день!
Искал повсюду ответ на простой вопрос и очень странно - не нашёл!
Плохо искали в каждой книге по VBA есть примеры работы с текстовыми файлами.
Если лень читать книги, то вот Вам пример разберетесь самостоятельно (это всего 1 вариант из десятков возможных).
Удачи
Код
Sub ReadTextFileFSO()
'''Чтение всего текстового файла
Dim objFile As Object, objFS As Object
Dim strFullFileName As String '' полный путь к файлу
Dim strRead As String
strFullFileName = "D:\Users\TSN\Desktop\WWWList.txt"
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objFile = objFS.OpenTextFile(strFullFileName, 1, True)
    strRead = objFile.ReadAll ''' копируем
              objFile.Close
   ActiveCell.Value = strRead ''' вставляем
Set objFS = Nothing: Set objFile = Nothing
strRead = vbNullString
End Sub
Изменено: TSN - 26.05.2017 15:40:09
Страницы: 1 2 3 4 5 6 7 8 След.
Наверх