Надо просто: 1. согласовать размер выходного массива с учётом откинутых строк ReDim M(UBound(A)-2, C) откинуть нужное количество
Во-первых, ReDim "убьёт" всё содержимое массива. Во-вторых можно было бы вставить Preserve, но массив то двумерный и это ни к чему не приведёт. Ну а здесь:
... организовать цикл с нужной строки по нужную For i = 2 To UBound(A) - 2 ' по всем строкам (с учётом, что массив А начинается с индекса = 0) 3. Согласовать индексы массивов при разбиении строк. типа M(i - 2, j) = T(j)
я реально "заблудился". Сложноватый вариант. Очень хотел разобраться, но мозги от циклов зациклились. Так что, остановлюсь на старом варианте. Он как то попроще будет, ну и попонятнее естественно.
Надо просто: 1. согласовать размер выходного массива с учётом откинутых строк ReDim M(UBound(A)-2, C) откинуть нужное количество
Во-первых, ReDim "убьёт" всё содержимое массива. Во-вторых можно было бы вставить Preserve, но массив то двумерный и это ни к чему не приведёт. Ну а здесь:
... организовать цикл с нужной строки по нужную For i = 2 To UBound(A) - 2 ' по всем строкам (с учётом, что массив А начинается с индекса = 0) 3. Согласовать индексы массивов при разбиении строк. типа M(i - 2, j) = T(j)
я реально "заблудился". Сложноватый вариант. Очень хотел разобраться, но мозги от циклов зациклились. Так что, остановлюсь на старом варианте. Он как то попроще будет, ну и попонятнее естественно.Vostok
"Посылая кого-то в Google, Помните, завтра туда могут Послать Вас !"
Сообщение отредактировал Vostok - Среда, 15.10.2014, 12:20
Естественно. Но если все файлы имеют одинаковую структуру и вы уверены, что первые три строки не являются носителями полезной информации и не нужны на листе, то и назначайте выходной массив на 3 меньше. Хотя даже можно этого не делать: обрабатывайте массив строк начиная с 4 строки, но записывайте в выходной массив начиная с 1 строки. Иначе при выгрузке на лист первые 3 строки будут пустыми.
Цитата
ReDim "убьёт" всё содержимое массива
Естественно. Но если все файлы имеют одинаковую структуру и вы уверены, что первые три строки не являются носителями полезной информации и не нужны на листе, то и назначайте выходной массив на 3 меньше. Хотя даже можно этого не делать: обрабатывайте массив строк начиная с 4 строки, но записывайте в выходной массив начиная с 1 строки. Иначе при выгрузке на лист первые 3 строки будут пустыми.alex77755
но записывайте в выходной массив начиная с 1 строки. Иначе при выгрузке на лист первые 3 строки будут пустыми.
Наверное это последний "гемморой" в теме. Вчера от циклов - чуть "крыша" не поехала. Сегодня всё исправил, при направляющей "руке" участвующих в теме(alex77755, AndreTM). Приведу к единому виду и выложу этот вариант с разъяснениями для публики. Может ещё у кого модернизация появится
но записывайте в выходной массив начиная с 1 строки. Иначе при выгрузке на лист первые 3 строки будут пустыми.
Наверное это последний "гемморой" в теме. Вчера от циклов - чуть "крыша" не поехала. Сегодня всё исправил, при направляющей "руке" участвующих в теме(alex77755, AndreTM). Приведу к единому виду и выложу этот вариант с разъяснениями для публики. Может ещё у кого модернизация появится Vostok
"Посылая кого-то в Google, Помните, завтра туда могут Послать Вас !"
Сообщение отредактировал Vostok - Четверг, 16.10.2014, 10:41
ИТОГОВОЕ РЕШЕНИЕ № 1 ДЛЯ ВАРИАНТА alex77755 (Работает с небольшими файлами *.csv. Тестировался с файлом в 1000 строк)(С комментариями для новичков)
Возможности: '1. Загрузка файла *.csv в двумерный массив '2. Сортирорвка в массиве по убыванию, так как в файле данные представлены по возрастанию '3. Установка в массиве нужного количества строк '3. Выгрузка на лист из массива полученного материала
[vba]
Код
Sub QWERT() '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'если в файле последняя дата находится сверху то считываем нужное количество строк (к примеру, 200) 'тут же с помощью аргумента функции Split, т.к. обрезка в данном случае производится снизу 'A = Split(CreateObject("Scripting.FileSystemObject").Getfile(NAME).OpenasTextStream(1).ReadAll, vbNewLine, 200)
Dim A() As String, NAME As String, Delimiter As String, i As Integer, j As Integer Dim C As String, T() As String, M() As Variant, Max As Date, Nm, TEM Application.ScreenUpdating = False Delimiter = "," NAME = ActiveWorkbook.Path & "\totalpc.csv"
'------------------------------------------считываем в массив файл totalpc.csv построчно () A = Split(CreateObject("Scripting.FileSystemObject").Getfile(NAME).OpenasTextStream(1).ReadAll, vbNewLine)
'по колич. запятых в строке А() определяем количество столбцов будущего двумерного массива C = UBound(Split(A(i), Delimiter)) '---------------------------------------определяем (устанавливаем)размер двумерного массива ReDim M(UBound(A), C) ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '-------Формирование двумерного массива с подготовкой Столбца Даты к последующей Сортировке For i = 2 To UBound(A) - 1 '---------------идём по всем строкам А(), не трогая заголовок '---------------------------DATE CALLS PUTS TOTAL P/C Ratio
T = Split(A(i), Delimiter) '--------------------разбиваем по столбцам строки массива A() '-----------------------------результат помещаем в массив Т() For j = 0 To C M(i - 2, j) = T(j) '------------------------------заполняем двумерный массив М() Next j '----------определяем Формат Даты, т.е. 1-ого Столбца для последующей Корректной Сортировки If IsDate(M(i - 2, 0)) Then T = Split(M(i - 2, 0), "/"): M(i - 2, 0) = DateSerial(T(2), T(0), T(1)) End If Next i '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '--- Сортировка двумерного массива --------------------------------------------------------- For i = 1 To UBound(A) - 1 Max = M(i, 0) Nm = i For j = i + 1 To UBound(A) If Max < M(j, 0) Then Max = M(j, 0): Nm = j End If Next j
For j = 0 To C TEM = M(i, j): M(i, j) = M(Nm, j): M(Nm, j) = TEM Next j M(i, 0) = Format(M(i, 0), "dd.mm.yyyy") Next i '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Dim NumRows As Integer NumRows = 150 'для вставки значения именнованной ячейки с листа Excel или пользовательской формы
M = Application.Transpose(M) 'транспон-ем массив, для возможности изменить колич. строк массива ReDim Preserve M(1 To UBound(M), 1 To NumRows) 'изменяем колич.строк массива через второй элемент M = Application.Transpose(M) '----возвращаем массив в прежнее состояние с нужным количеством строк
'-------------------------------------------------------------------------------выгружаем на лист Worksheets("Лист1").Cells.ClearContents Worksheets("Лист1").Range("A1").Resize(UBound(M, 1), UBound(M, 2)).Columns(1).NumberFormat = "dd.mm.yyyy" Worksheets("Лист1").Range("A1").Resize(UBound(M, 1), UBound(M, 2)) = M Application.ScreenUpdating = True End Sub
[/vba]
ИТОГОВОЕ РЕШЕНИЕ № 1 ДЛЯ ВАРИАНТА alex77755 (Работает с небольшими файлами *.csv. Тестировался с файлом в 1000 строк)(С комментариями для новичков)
Возможности: '1. Загрузка файла *.csv в двумерный массив '2. Сортирорвка в массиве по убыванию, так как в файле данные представлены по возрастанию '3. Установка в массиве нужного количества строк '3. Выгрузка на лист из массива полученного материала
[vba]
Код
Sub QWERT() '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'если в файле последняя дата находится сверху то считываем нужное количество строк (к примеру, 200) 'тут же с помощью аргумента функции Split, т.к. обрезка в данном случае производится снизу 'A = Split(CreateObject("Scripting.FileSystemObject").Getfile(NAME).OpenasTextStream(1).ReadAll, vbNewLine, 200)
Dim A() As String, NAME As String, Delimiter As String, i As Integer, j As Integer Dim C As String, T() As String, M() As Variant, Max As Date, Nm, TEM Application.ScreenUpdating = False Delimiter = "," NAME = ActiveWorkbook.Path & "\totalpc.csv"
'------------------------------------------считываем в массив файл totalpc.csv построчно () A = Split(CreateObject("Scripting.FileSystemObject").Getfile(NAME).OpenasTextStream(1).ReadAll, vbNewLine)
'по колич. запятых в строке А() определяем количество столбцов будущего двумерного массива C = UBound(Split(A(i), Delimiter)) '---------------------------------------определяем (устанавливаем)размер двумерного массива ReDim M(UBound(A), C) ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '-------Формирование двумерного массива с подготовкой Столбца Даты к последующей Сортировке For i = 2 To UBound(A) - 1 '---------------идём по всем строкам А(), не трогая заголовок '---------------------------DATE CALLS PUTS TOTAL P/C Ratio
T = Split(A(i), Delimiter) '--------------------разбиваем по столбцам строки массива A() '-----------------------------результат помещаем в массив Т() For j = 0 To C M(i - 2, j) = T(j) '------------------------------заполняем двумерный массив М() Next j '----------определяем Формат Даты, т.е. 1-ого Столбца для последующей Корректной Сортировки If IsDate(M(i - 2, 0)) Then T = Split(M(i - 2, 0), "/"): M(i - 2, 0) = DateSerial(T(2), T(0), T(1)) End If Next i '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '--- Сортировка двумерного массива --------------------------------------------------------- For i = 1 To UBound(A) - 1 Max = M(i, 0) Nm = i For j = i + 1 To UBound(A) If Max < M(j, 0) Then Max = M(j, 0): Nm = j End If Next j
For j = 0 To C TEM = M(i, j): M(i, j) = M(Nm, j): M(Nm, j) = TEM Next j M(i, 0) = Format(M(i, 0), "dd.mm.yyyy") Next i '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Dim NumRows As Integer NumRows = 150 'для вставки значения именнованной ячейки с листа Excel или пользовательской формы
M = Application.Transpose(M) 'транспон-ем массив, для возможности изменить колич. строк массива ReDim Preserve M(1 To UBound(M), 1 To NumRows) 'изменяем колич.строк массива через второй элемент M = Application.Transpose(M) '----возвращаем массив в прежнее состояние с нужным количеством строк
'-------------------------------------------------------------------------------выгружаем на лист Worksheets("Лист1").Cells.ClearContents Worksheets("Лист1").Range("A1").Resize(UBound(M, 1), UBound(M, 2)).Columns(1).NumberFormat = "dd.mm.yyyy" Worksheets("Лист1").Range("A1").Resize(UBound(M, 1), UBound(M, 2)) = M Application.ScreenUpdating = True End Sub
'транспон-ем массив, для возможности изменить колич. строк массива
Стесняюсь спросить: а зачем эти танци с бубном? Почему сразу не сделать [vba]
Код
ReDim M(150, C) For i = 2 To 152
[/vba] Разумеется сначала проверив UBound(A). Если он меньше 150, то назначать UBound(A) Зачем делать лишние преобразования массива строк А в двумерный массив М, что бы потом его обрезать? Да ещё применяя функцию Transpose имеющую ряд ограничений:
Массив не может содержать элементов, длина которых превышает 255 знаков.
Массив не может содержать пустые (Null) значения.
Количество элементов не может превышать 5461.
Цитата
'транспон-ем массив, для возможности изменить колич. строк массива
Стесняюсь спросить: а зачем эти танци с бубном? Почему сразу не сделать [vba]
Код
ReDim M(150, C) For i = 2 To 152
[/vba] Разумеется сначала проверив UBound(A). Если он меньше 150, то назначать UBound(A) Зачем делать лишние преобразования массива строк А в двумерный массив М, что бы потом его обрезать? Да ещё применяя функцию Transpose имеющую ряд ограничений:
Массив не может содержать элементов, длина которых превышает 255 знаков.
Стесняюсь спросить: а зачем эти танци с бубном? Почему сразу не сделать ReDim M(150, C) For i = 2 To 152
К сожалению, ни без танцев , ни без бубна в данном случае не обойтись. Если сделать как Вы предложили у нас останутся только 150 строк от первоначального файла *.csv и "свежие" даты, которые находятся внизу файла обрежутся. А они то нам и нужны в первую очередь. Если бы файл *.csv давал данные сверху-вниз от сегоднейшей даты к старой - не вопрос. Вот в этом вся хрень с этими *.csv и заключается, из-за этого вся эта тема на три листа и растянулась.
Да ещё применяя функцию Transpose имеющую ряд ограничений: Массив не может содержать элементов, длина которых превышает 255 знаков. Массив не может содержать пустые (Null) значения. Количество элементов не может превышать 5461.
Ну а с этим согласен. На больших файлах будет сбой. Но вот сейчас взял файл в 1000 строк - отработал на Ура. Ну а вообще, для больших файлов возьмём для транспонирования пользовательскую функцию. Есть такая. Позже приведу её здесь, после тестов.
Стесняюсь спросить: а зачем эти танци с бубном? Почему сразу не сделать ReDim M(150, C) For i = 2 To 152
К сожалению, ни без танцев , ни без бубна в данном случае не обойтись. Если сделать как Вы предложили у нас останутся только 150 строк от первоначального файла *.csv и "свежие" даты, которые находятся внизу файла обрежутся. А они то нам и нужны в первую очередь. Если бы файл *.csv давал данные сверху-вниз от сегоднейшей даты к старой - не вопрос. Вот в этом вся хрень с этими *.csv и заключается, из-за этого вся эта тема на три листа и растянулась.
Да ещё применяя функцию Transpose имеющую ряд ограничений: Массив не может содержать элементов, длина которых превышает 255 знаков. Массив не может содержать пустые (Null) значения. Количество элементов не может превышать 5461.
Ну а с этим согласен. На больших файлах будет сбой. Но вот сейчас взял файл в 1000 строк - отработал на Ура. Ну а вообще, для больших файлов возьмём для транспонирования пользовательскую функцию. Есть такая. Позже приведу её здесь, после тестов.
A = Split(CreateObject("Scripting.FileSystemObject").Getfile(NAME).OpenasTextStream(1).ReadAll, vbNewLine)
[/vba] и перевернуть его с "ног на голову" (реверс), чтобы старые данные оказались внизу, а свежие - вверху. А потом задать размер двумерного массива, обрезав старые данные (обрежутся снизу). Тогда бы транспонирование в будущем не потребовалось. Но тут я "завис". Вроде простая операция на первый взгляд, но у меня пока ничего не получилось. Вылетают ошибки одна за другой, не разобрался.
Была ещё идея. Взять массив А() [vba]
Код
A = Split(CreateObject("Scripting.FileSystemObject").Getfile(NAME).OpenasTextStream(1).ReadAll, vbNewLine)
[/vba] и перевернуть его с "ног на голову" (реверс), чтобы старые данные оказались внизу, а свежие - вверху. А потом задать размер двумерного массива, обрезав старые данные (обрежутся снизу). Тогда бы транспонирование в будущем не потребовалось. Но тут я "завис". Вроде простая операция на первый взгляд, но у меня пока ничего не получилось. Вылетают ошибки одна за другой, не разобрался.Vostok
"Посылая кого-то в Google, Помните, завтра туда могут Послать Вас !"
Сообщение отредактировал Vostok - Пятница, 17.10.2014, 06:34
Примерно так (если надо без шапки) Если шапка нужна - добавить цикл дописи шапки и сортировка тогда не с 1 строки:
[vba]
Код
Sub QWERT()
Dim A() As String, NAME, Delimiter, i, J, C, T() As String, M(), Max As Date, Nm, TEM
Delimiter = "," NAME = ActiveWorkbook.Path & "\totalpc.csv" ' читаем в массив строки A = Split(CreateObject("Scripting.FileSystemObject").Getfile(NAME).OpenasTextStream(1).ReadAll, vbNewLine) C = UBound(Split(A(i), Delimiter))
Dim STROK As Long, L STROK = InputBox("Скока строк из " & UBound(A) - 3 & " с конца списка наадо вывести без 3 строк шапки?", "", 150) ' STROK = IIf(UBound(A) < 150, UBound(A), 150)
ReDim M(1 To STROK, C) For i = UBound(A) - 1 To UBound(A) - STROK Step -1 ' по всем строкам L = L + 1 T = Split(A(i), Delimiter) ' разбиваем по элементам For J = 0 To C M(L, J) = T(J) Next J If IsDate(M(L, 0)) Then: T = Split(M(L, 0), "/"): M(L, 0) = DateSerial(T(2), T(0), T(1)) Next i
'cортировка For i = 1 To UBound(M) Max = M(i, 0) Nm = i For J = i + 1 To UBound(M) If Max < M(J, 0) Then Max = M(J, 0) Nm = J End If Next J For J = 0 To C TEM = M(i, J) M(i, J) = M(Nm, J) M(Nm, J) = TEM Next J M(i, 0) = Format(M(i, 0), "dd.mm.yyyy") Next i Лист2.Cells.ClearContents Лист2.Range("A1").Resize(UBound(M), UBound(M, 2) + 1) = M MsgBox "ok", 64, "" End Sub
[/vba]
Без проверки корректности ответа на запрос
Для организации проверок на корректность заменить строку на блок:
[vba]
Код
Dim STROK As Long, L ' для проверок строку ' STROK = InputBox("Скока строк из " & UBound(A) - 3 & " с конца списка наадо вывести без 3 строк шапки?", "", 150)
' заменить на блок с проверками TEM = InputBox("Скока строк из " & UBound(A) - 3 & " с конца списка наадо вывести без 3 строк шапки?", "", 150) If TEM = "" Then Exit Sub ' нажали отмена If IsNumeric(TEM) Then STROK = TEM If STROK < UBound(A) Then Exit Do End If Loop
' STROK = IIf(UBound(A) < 150, UBound(A), 150)
[/vba]
Примерно так (если надо без шапки) Если шапка нужна - добавить цикл дописи шапки и сортировка тогда не с 1 строки:
[vba]
Код
Sub QWERT()
Dim A() As String, NAME, Delimiter, i, J, C, T() As String, M(), Max As Date, Nm, TEM
Delimiter = "," NAME = ActiveWorkbook.Path & "\totalpc.csv" ' читаем в массив строки A = Split(CreateObject("Scripting.FileSystemObject").Getfile(NAME).OpenasTextStream(1).ReadAll, vbNewLine) C = UBound(Split(A(i), Delimiter))
Dim STROK As Long, L STROK = InputBox("Скока строк из " & UBound(A) - 3 & " с конца списка наадо вывести без 3 строк шапки?", "", 150) ' STROK = IIf(UBound(A) < 150, UBound(A), 150)
ReDim M(1 To STROK, C) For i = UBound(A) - 1 To UBound(A) - STROK Step -1 ' по всем строкам L = L + 1 T = Split(A(i), Delimiter) ' разбиваем по элементам For J = 0 To C M(L, J) = T(J) Next J If IsDate(M(L, 0)) Then: T = Split(M(L, 0), "/"): M(L, 0) = DateSerial(T(2), T(0), T(1)) Next i
'cортировка For i = 1 To UBound(M) Max = M(i, 0) Nm = i For J = i + 1 To UBound(M) If Max < M(J, 0) Then Max = M(J, 0) Nm = J End If Next J For J = 0 To C TEM = M(i, J) M(i, J) = M(Nm, J) M(Nm, J) = TEM Next J M(i, 0) = Format(M(i, 0), "dd.mm.yyyy") Next i Лист2.Cells.ClearContents Лист2.Range("A1").Resize(UBound(M), UBound(M, 2) + 1) = M MsgBox "ok", 64, "" End Sub
[/vba]
Без проверки корректности ответа на запрос
Для организации проверок на корректность заменить строку на блок:
[vba]
Код
Dim STROK As Long, L ' для проверок строку ' STROK = InputBox("Скока строк из " & UBound(A) - 3 & " с конца списка наадо вывести без 3 строк шапки?", "", 150)
' заменить на блок с проверками TEM = InputBox("Скока строк из " & UBound(A) - 3 & " с конца списка наадо вывести без 3 строк шапки?", "", 150) If TEM = "" Then Exit Sub ' нажали отмена If IsNumeric(TEM) Then STROK = TEM If STROK < UBound(A) Then Exit Do End If Loop
Как видно, при правильном подходе сортировка оказалась вообще не нужна. Просто прошлись с конца файла с самого начала и всё. В сравнении с вариантом в"Сообщении 25" этот в 10 раз короче.
[vba]
Код
Sub QWERT_2() Dim A() As String, NAME, Delimiter, i, J, C, T() As String, M() Delimiter = "," NAME = ActiveWorkbook.Path & "\totalpc1000.csv" 'в файле - 1000 строк ' читаем в массив строки A = Split(CreateObject("Scripting.FileSystemObject").Getfile(NAME).OpenasTextStream(1).ReadAll, vbNewLine) C = UBound(Split(A(i), Delimiter)) Application.ScreenUpdating = False Dim STROK As Long, L STROK = 300
ReDim M(STROK, C) T = Split(A(2), Delimiter) ' Добавляем Шапку из строки A(2): DATE CALLS PUTS TOTAL P/C Ratio For J = 0 To C M(0, J) = T(J) Next J
For i = UBound(A) - 1 To UBound(A) - STROK Step -1 'из строк массива A() создаём двумерный массив M() L = L + 1 T = Split(A(i), Delimiter) For J = 0 To C M(L, J) = T(J) Next J If IsDate(M(L, 0)) Then: T = Split(M(L, 0), "/"): M(L, 0) = DateSerial(T(2), T(0), T(1)) Next i
Лист2.Cells.ClearContents Лист2.Range("A1").Resize(UBound(M), UBound(M, 2) + 1) = M Application.ScreenUpdating = True End Sub
[/vba]
ИТОГОВОЕ РЕШЕНИЕ № 2 ДЛЯ ВАРИАНТА alex77755
Как видно, при правильном подходе сортировка оказалась вообще не нужна. Просто прошлись с конца файла с самого начала и всё. В сравнении с вариантом в"Сообщении 25" этот в 10 раз короче.
[vba]
Код
Sub QWERT_2() Dim A() As String, NAME, Delimiter, i, J, C, T() As String, M() Delimiter = "," NAME = ActiveWorkbook.Path & "\totalpc1000.csv" 'в файле - 1000 строк ' читаем в массив строки A = Split(CreateObject("Scripting.FileSystemObject").Getfile(NAME).OpenasTextStream(1).ReadAll, vbNewLine) C = UBound(Split(A(i), Delimiter)) Application.ScreenUpdating = False Dim STROK As Long, L STROK = 300
ReDim M(STROK, C) T = Split(A(2), Delimiter) ' Добавляем Шапку из строки A(2): DATE CALLS PUTS TOTAL P/C Ratio For J = 0 To C M(0, J) = T(J) Next J
For i = UBound(A) - 1 To UBound(A) - STROK Step -1 'из строк массива A() создаём двумерный массив M() L = L + 1 T = Split(A(i), Delimiter) For J = 0 To C M(L, J) = T(J) Next J If IsDate(M(L, 0)) Then: T = Split(M(L, 0), "/"): M(L, 0) = DateSerial(T(2), T(0), T(1)) Next i
Лист2.Cells.ClearContents Лист2.Range("A1").Resize(UBound(M), UBound(M, 2) + 1) = M Application.ScreenUpdating = True End Sub
Тема та же, но файл .csv другой. Одно не пойму - он практически не отличается от предыдущего, но строка [vba]
Код
A = Split(CreateObject("Scripting.FileSystemObject").Getfile(LINK).OpenasTextStream(1).ReadAll, vbNewLine)
[/vba] отказывается работать. Split не может корректно разбить строку. Как побороть это файл, ума не приложу.
Он, кстати, и стандартным методом разбиения по столбцам в Excel отказывается "биться" корректно с сохранением данных. Интересует собственно работа этой строки кода, далее - занесение в массив, всё должно работать правильно.
Приложил ещё тот же файл, но оригинальный с сайта. Его качал и его сохранял под новым именем. Этот новый файл и используется в примере. Может при сохранении что то нарушилось в структуре? Хотя я и его пробовал обрабатывать, та же история.
Тема та же, но файл .csv другой. Одно не пойму - он практически не отличается от предыдущего, но строка [vba]
Код
A = Split(CreateObject("Scripting.FileSystemObject").Getfile(LINK).OpenasTextStream(1).ReadAll, vbNewLine)
[/vba] отказывается работать. Split не может корректно разбить строку. Как побороть это файл, ума не приложу.
Он, кстати, и стандартным методом разбиения по столбцам в Excel отказывается "биться" корректно с сохранением данных. Интересует собственно работа этой строки кода, далее - занесение в массив, всё должно работать правильно.
Приложил ещё тот же файл, но оригинальный с сайта. Его качал и его сохранял под новым именем. Этот новый файл и используется в примере. Может при сохранении что то нарушилось в структуре? Хотя я и его пробовал обрабатывать, та же история.Vostok
A = Split(CreateObject("Scripting.FileSystemObject").Getfile(LINK).OpenasTextStream(1).ReadAll, vbNewLine) If ubound(A)<2 then A = Split(CreateObject("Scripting.FileSystemObject").Getfile(LINK).OpenasTextStream(1).ReadAll, vbLf)
[/vba] Откройте файл Notepad++,включите опцию отображать символы переноса,все станет понятно. Но я бы при таких вариантах читал построчно и создал бы пользовательский тип свеча и добавлял в массив Свечи
[vba]
Код
A = Split(CreateObject("Scripting.FileSystemObject").Getfile(LINK).OpenasTextStream(1).ReadAll, vbNewLine) If ubound(A)<2 then A = Split(CreateObject("Scripting.FileSystemObject").Getfile(LINK).OpenasTextStream(1).ReadAll, vbLf)
[/vba] Откройте файл Notepad++,включите опцию отображать символы переноса,все станет понятно. Но я бы при таких вариантах читал построчно и создал бы пользовательский тип свеча и добавлял в массив Свечиdoober
Откройте файл Notepad++,включите опцию отображать символы переноса,все станет понятно.
Вот как чувствовал что всё дело в символах переноса, а как их увидеть - не знал. Спасибо за помощь. У данного файла стоит символ переноса Lf и вы применили константу vbLf. У ранее рассмотренного в прошлых примерах файла .csv был перенос CRLf и отрабатывала константа vbNewLine.
А какие ещё бывают символы переноса и подходящие к ним константы VBA. Где об этом хотя бы почитать можно? Изучаю Уокенбаха, и постоянно какие-то вопросы зависают. Что-то он не очень информативен.
Кстати, с этим символом переноса (Lf) похоже и сам Excel не справляется , в смысле по разбивке на столбы стандартным способом.
Откройте файл Notepad++,включите опцию отображать символы переноса,все станет понятно.
Вот как чувствовал что всё дело в символах переноса, а как их увидеть - не знал. Спасибо за помощь. У данного файла стоит символ переноса Lf и вы применили константу vbLf. У ранее рассмотренного в прошлых примерах файла .csv был перенос CRLf и отрабатывала константа vbNewLine.
А какие ещё бывают символы переноса и подходящие к ним константы VBA. Где об этом хотя бы почитать можно? Изучаю Уокенбаха, и постоянно какие-то вопросы зависают. Что-то он не очень информативен.
Кстати, с этим символом переноса (Lf) похоже и сам Excel не справляется , в смысле по разбивке на столбы стандартным способом.
Private Type Свеча Date_ As Date CALLS As Double PUTS As Double Total As Double Ratio As Double End Type
Sub ReadCsv() Dim R R = CsvToarray("d:\totalpc.csv") Range("A1").Resize(UBound(r) + 1, UBound(R, 2) + 1) = R
End Sub Private Function CsvToarray(Fname As String) Dim Свеча() As Свеча, Last As Long, Z As Variant, s As String, Rez As Variant Last = -1 Set FSO = CreateObject("scripting.filesystemobject") '--- читаем текст из выбранного файла Set ts = FSO.OpenTextFile(Fname, 1, True) Do Until ts.AtEndOfStream s = Replace(ts.ReadLine, " ", "") Z = Split(s, ",") If IsDate(Z(0)) Then Last = Last + 1 ReDim Preserve Свеча(Last) ' Свеча(Last).Date_ = CDate(Z(0)) Заменил строку Свеча(Last).Date_ = Format(Z(0), "mm.dd.yy") Свеча(Last).CALLS = Val(Z(1)) Свеча(Last).PUTS = Val(Z(2)) Свеча(Last).Total = Val(Z(3)) Свеча(Last).Ratio = Val(Z(4)) End If Loop ts.Close Set FSO = Nothing Set ts = Nothing Bubble Свеча ReDim Rez(UBound(Свеча) + 1, 4) Rez(0, 0) = "DATE" Rez(0, 1) = "CALLS" Rez(0, 2) = "PUTS" Rez(0, 3) = "Total" Rez(0, 4) = "Ratio"
For n = 0 To UBound(Свеча) Rez(n + 1, 0) = Свеча(n).Date_ Rez(n + 1, 1) = Свеча(n).CALLS Rez(n + 1, 2) = Свеча(n).PUTS Rez(n + 1, 3) = Свеча(n).Total Rez(n + 1, 4) = Свеча(n).Ratio Next CsvToarray = Rez End Function
Private Sub Bubble(ByRef List() As Свеча) Dim First As Integer, Last As Long Dim i As Long, j As Long Dim Temp As Свеча First = LBound(List) Last = UBound(List) For i = First To Last - 1 For j = i + 1 To Last If List(i).Date_ > List(j).Date_ Then Temp = List(j) List(j) = List(i) List(i) = Temp End If Next j Next i End Sub
[/vba]
Внес изменения
Дождались?
[vba]
Код
Private Type Свеча Date_ As Date CALLS As Double PUTS As Double Total As Double Ratio As Double End Type
Sub ReadCsv() Dim R R = CsvToarray("d:\totalpc.csv") Range("A1").Resize(UBound(r) + 1, UBound(R, 2) + 1) = R
End Sub Private Function CsvToarray(Fname As String) Dim Свеча() As Свеча, Last As Long, Z As Variant, s As String, Rez As Variant Last = -1 Set FSO = CreateObject("scripting.filesystemobject") '--- читаем текст из выбранного файла Set ts = FSO.OpenTextFile(Fname, 1, True) Do Until ts.AtEndOfStream s = Replace(ts.ReadLine, " ", "") Z = Split(s, ",") If IsDate(Z(0)) Then Last = Last + 1 ReDim Preserve Свеча(Last) ' Свеча(Last).Date_ = CDate(Z(0)) Заменил строку Свеча(Last).Date_ = Format(Z(0), "mm.dd.yy") Свеча(Last).CALLS = Val(Z(1)) Свеча(Last).PUTS = Val(Z(2)) Свеча(Last).Total = Val(Z(3)) Свеча(Last).Ratio = Val(Z(4)) End If Loop ts.Close Set FSO = Nothing Set ts = Nothing Bubble Свеча ReDim Rez(UBound(Свеча) + 1, 4) Rez(0, 0) = "DATE" Rez(0, 1) = "CALLS" Rez(0, 2) = "PUTS" Rez(0, 3) = "Total" Rez(0, 4) = "Ratio"
For n = 0 To UBound(Свеча) Rez(n + 1, 0) = Свеча(n).Date_ Rez(n + 1, 1) = Свеча(n).CALLS Rez(n + 1, 2) = Свеча(n).PUTS Rez(n + 1, 3) = Свеча(n).Total Rez(n + 1, 4) = Свеча(n).Ratio Next CsvToarray = Rez End Function
Private Sub Bubble(ByRef List() As Свеча) Dim First As Integer, Last As Long Dim i As Long, j As Long Dim Temp As Свеча First = LBound(List) Last = UBound(List) For i = First To Last - 1 For j = i + 1 To Last If List(i).Date_ > List(j).Date_ Then Temp = List(j) List(j) = List(i) List(i) = Temp End If Next j Next i End Sub