Загрузка excel в массив

0 / 0 / 0

Регистрация: 13.07.2012

Сообщений: 23

1

18.09.2012, 09:18. Показов 36449. Ответов 18


Студворк — интернет-сервис помощи студентам

Создал макрос в VISIO2010, но столкнулся с проблемой. Как загружать в массив данные из Excel. Есть ли такая возможность??????



0



Скрипт

5468 / 1148 / 50

Регистрация: 15.09.2012

Сообщений: 3,514

18.09.2012, 09:44

2

Лучший ответ Сообщение было отмечено как решение

Решение

Я так понимаю, что в VBA есть 2 способа создания массивов на основе данных Excel:

  1. непосредственное создание массива:
    Visual Basic
    1
    2
    3
    4
    5
    6
    
    Sub Procedure_1()
        
        'Круглые скобки указывают, что мы создаём массив.
        Dim Массив() As Long
        
    End Sub
  2. создание переменной, а затем превращение её в массив (тип данных у переменной должен быть обязательно Variant):
    Visual Basic
    1
    2
    3
    4
    5
    
    Sub Procedure_2()
     
       Dim Массив As Variant
     
    End Sub

1 случай.

В этом случае массив можно заполнить только с помощью цикла.

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
Sub Procedure_1()
    
    'Круглые скобки указывают, что мы создаём массив.
    Dim Массив() As Long
    Dim i As Long
    
    ReDim Массив(1 To 2)
    
    For i = 1 To 2 Step 1
        Массив(i) = Cells(i, "A").Value
    Next i
    
End Sub

2 случай.

В этом случае можно заполнить массив, присвоив ему диапазон Excel.

Visual Basic
1
2
3
4
5
6
7
Sub Procedure_2()
 
   Dim Массив As Variant
    
   Массив = Range("A1:A2").Value
   
End Sub

Примечания по второму случаю:

  • создать массив можно только присвоив 2 и более ячейки;
  • по умолчанию порядковый номер элемента массива ноль. Но в данном случае, порядковый номер первого элемента массива Массив(1, 1);
  • всегда будет создаваться двумерный массив, т.е. координаты первого элемента массива будут: Массив(1, 1).



0



0 / 0 / 0

Регистрация: 13.07.2012

Сообщений: 23

18.09.2012, 09:48

 [ТС]

3

Это понятно…но как в Visio 2010 «перегнать» этот массив?



0



0 / 0 / 0

Регистрация: 13.07.2012

Сообщений: 23

18.09.2012, 09:54

 [ТС]

4

Задача такая данные забиваются с таблицу Excel, потом надо эти данные «перегнать» в Visio. В Visio с кодом проблем нету. И массив есть не загонять через InputBox офигеешь. Один ляп и работа коту под хвост. Пытался из строки в Visio загружать, но это еще то извращение….не чем не лучше InputBox



0



Казанский

15136 / 6410 / 1730

Регистрация: 24.09.2011

Сообщений: 9,999

18.09.2012, 10:03

5

Немного дополню.

2 случай

Лучше объявить так

Visual Basic
1
Dim Массив() 'As Variant

В этом случае Массив имеет тип Variant(), а не Variant/Variant(), и доступ к его элементам происходит быстрее.

1 случай

Если предстоит много работы с массивом определенного типа (например, Double), то, конечно, лучше переписать данные из массива Variant в массив нужного типа:

Visual Basic
1
2
3
4
5
6
7
8
9
10
Dim Массив() As Double, tmp(), i&, j&
 
tmp = Range("A1:G100").Value
ReDim Массив(1 To UBound(tmp), 1 To UBound(tmp, 2))
For i = 1 To UBound(Массив)
    For j = 1 To UBound(Массив, 2)
        Массив(i, j) = tmp(i, j)
    Next
Next
Erase tmp



2



0 / 0 / 0

Регистрация: 13.07.2012

Сообщений: 23

18.09.2012, 10:05

 [ТС]

6

Согласен Varian лучше, но как эти данные «подхватить» в Visio?



0



Скрипт

5468 / 1148 / 50

Регистрация: 15.09.2012

Сообщений: 3,514

18.09.2012, 10:08

7

В Visio в VBA: ToolsReferences…Microsoft Excel Object Library;
В Visio в VBA:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Sub Procedure_1()
 
    'В константе нужно указать путь и имя книги Excel.
    Const sPath As String = "C:UsersUserDesktopКнига1.xlsx"
 
    'Запускаем программу Excel.
    Dim oExcel As New Excel.Application
    
    Dim oWorkbook As Excel.Workbook
    Dim Массив As Variant
    
    'Делаем программу Excel видимой.
    oExcel.Visible = True
    
    'Открываем книгу Excel, из которой надо взять данные.
    'Присваиваем этой книге имя "oWorkbook", через которое будет обращаться к ней.
    Set oWorkbook = oExcel.Workbooks.Open(FileName:=sPath)
    
    'Берём в массив данные с первого листа из двух ячеек.
    Массив = oWorkbook.Worksheets(1).Range("A1:A2").Value
    
End Sub



0



0 / 0 / 0

Регистрация: 13.07.2012

Сообщений: 23

18.09.2012, 10:10

 [ТС]

8

Спасибо! Попробую))))



0



Скрипт

5468 / 1148 / 50

Регистрация: 15.09.2012

Сообщений: 3,514

18.09.2012, 10:19

9

Казанский, такой случай где-нибудь написан (в справке Microsoft Office, на сайте Microsoft)?

Visual Basic
1
2
3
4
5
6
7
Sub Procedure_2()
 
   Dim Массив() As Variant
    
   Массив = Range("A1:A2").Value
   
End Sub



0



Dragokas

Эксперт WindowsАвтор FAQ

17992 / 7618 / 890

Регистрация: 25.12.2011

Сообщений: 11,352

Записей в блоге: 17

18.09.2012, 11:43

10

Для колонок обычно используют транспонирование в одномерный массив:

Visual Basic
1
Массив = Application.Transpose(Range("A1:A2").Value)



1



15136 / 6410 / 1730

Регистрация: 24.09.2011

Сообщений: 9,999

18.09.2012, 12:08

11

Цитата
Сообщение от Скрипт
Посмотреть сообщение

такой случай где-нибудь написан (в справке Microsoft Office, на сайте Microsoft)?

Наверняка где-то написано! В Справке есть «намек»

Цитата
Сообщение от F1 — Range.Value Property

Returns or sets a Variant value that represents the value of the specified range… If the Range object contains more than one cell, returns an array of values (use the IsArray function to test for this case).

Некоторые другие свойства диапазона тоже возвращают массив: .Formula, .FormulaR1C1, .FormulaLocal, .FormulaR1C1Local.
Но большинство свойств не возвращают массив значений свойства, если это свойство разное для разных ячеек диапазона, а возвращает Null. Например, свойства .Text, .Interior.ColorIndex и т.п.



2



5468 / 1148 / 50

Регистрация: 15.09.2012

Сообщений: 3,514

18.09.2012, 12:12

12

Я перепутал что-то. Я почему-то подумал, что нельзя в один массив поместить другой массив. Тогда всё правильно.



0



Казанский

15136 / 6410 / 1730

Регистрация: 24.09.2011

Сообщений: 9,999

18.09.2012, 22:22

13

Лучший ответ Сообщение было отмечено как решение

Решение

Цитата
Сообщение от Dragokas
Посмотреть сообщение

Для колонок обычно используют транспонирование в одномерный массив:

Visual Basic
1
Массив = Application.Transpose(Range("A1:A2").Value)

Тут есть нюанс!
Если метод применяется к МАССИВУ, у него есть ограничение на число элементов массива в ранних версиях Excel (http://support.microsoft.com/kb/177991), например, для Excel 2000 — 5461. То есть

Visual Basic
1
2
3
' Excel 2000
Массив = Application.Transpose(Range("A1:A5461").Value) 'работает
Массив = Application.Transpose(Range("A1:A5462").Value) 'НЕ работает

Однако, если метод применять к ДИАПАЗОНУ, то ограничения на число элементов нет — хватило бы памяти

Visual Basic
1
2
' Excel 2000
Массив = Application.Transpose(Range("A1:A65536")) 'работает!

Если в ячейках или в элементах массива содержится текст, его длина не должна превышать 255 символов. Например, если в А1 вставить формулу

Код

=ПОВТОР("а";256)

, то Transpose не сработает даже в Excel 2007. Поэтому для серьезных проектов метод Application.Transpose применять рискованно, лучше написать цикл.



3



Dragokas

18.09.2012, 23:51

Не по теме:

Казанский, спасибо. Перестаю давать злые советы :D



0



Sasha_Smirnov

5561 / 1367 / 150

Регистрация: 08.02.2009

Сообщений: 4,107

Записей в блоге: 30

19.09.2012, 02:20

15

Цитата
Сообщение от Казанский
Посмотреть сообщение

Visual Basic
1
ReDim Массив(1 To UBound(tmp), 1 To UBound(tmp, 2))

я бы так записал:

Visual Basic
1
ReDim Массив(1 To UBound(tmp, 1) To UBound(tmp, 2))

Как видим, Массив получает 1-ю и 2-ю размерности от tmp, угу?



0



ikki

призрак

3261 / 889 / 119

Регистрация: 11.05.2012

Сообщений: 1,702

Записей в блоге: 2

19.09.2012, 02:27

16

Цитата
Сообщение от Sasha_Smirnov
Посмотреть сообщение

ReDim Массив(1 To UBound(tmp, 1) To UBound(tmp, 2))

синтаксическая ошибка.

если уж оч.хочется:

Visual Basic
1
ReDim Массив(1 To UBound(tmp, 1), 1 To UBound(tmp, 2))

но, конечно, это то же самое, что и

Visual Basic
1
ReDim Массив(1 To UBound(tmp), 1 To UBound(tmp, 2))



0



5561 / 1367 / 150

Регистрация: 08.02.2009

Сообщений: 4,107

Записей в блоге: 30

19.09.2012, 04:03

17

Это ж первый раз я не протестировал код для форума, и всё — не выпилить!

Зато раскрылась некоторая гибкость нашего ЯП…

Не по теме:

…что напомнило анекдот:

— Почему ваша красная смородина белая?
— Да потому что она ещё зелёная.

Миниатюры

Как загружать в массив данные из Excel
 



0



Казанский

15136 / 6410 / 1730

Регистрация: 24.09.2011

Сообщений: 9,999

19.09.2012, 11:07

18

Так, с преобразованием диапазона-столбца в одномерный массив разобрались
Теперь — как преобразовать диапазон-строку в одномерный массив?
Как написал на Планете гуру Слэн,

просто повторите операцию.. только быстро

Visual Basic
1
mas = Application.Transpose(Application.Transpose(Лист1.Range("A1:D1")))



0



m-ch

6169 / 934 / 309

Регистрация: 25.02.2011

Сообщений: 1,359

Записей в блоге: 1

19.09.2012, 14:20

19

Лучший ответ Сообщение было отмечено как решение

Решение

может так?

Visual Basic
1
mas = Application.Index(Лист1.Range("A1:D1").Value, 1, 0)



2



Сделал!
Вернее нашел решения вот тут: stackoverflow.com и вот тут csharpcoderr.com и немного переделал.

Нижеприведенный программный код (написанный на языке C#) считывает данные из указанного столбца таблицы Excel (целиком весь столбец сразу) и записывает в одномерный массив strArray. Тип данных, хранимых в результирующем одномерном массиве — string.

//Создаём приложение.
        Microsoft.Office.Interop.Excel.Application ObjExcel = new Microsoft.Office.Interop.Excel.Application();
        //Открываем книгу.                                                                                                                                                        
        Microsoft.Office.Interop.Excel.Workbook ObjWorkBook = ObjExcel.Workbooks.Open(pathToFile, 0, false, 5, "", "", false, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "", true, false, 0, true, false, false);
        //Выбираем таблицу(лист).
        Microsoft.Office.Interop.Excel.Worksheet ObjWorkSheet;
        ObjWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)ObjWorkBook.Sheets[1];

        // Указываем номер столбца (таблицы Excel) из которого будут считываться данные.
        int numCol = 2;
    
        Range usedColumn = ObjWorkSheet.UsedRange.Columns[numCol];
        System.Array myvalues = (System.Array)usedColumn.Cells.Value2;
        string[] strArray = myvalues.OfType<object>().Select(o => o.ToString()).ToArray();

        // Выходим из программы Excel.
        ObjExcel.Quit();

где:
1) pathToFile — путь к Excel файлу.
Можно указать нижеприведенным способом:
string pathToFile = @"C:Usersalexeydata.xlsx";

2) numCol — номер столбца в таблице Excel из которого будет происходить чтение данных.

Если нужно будет преобразовать все полученные элементы одномерного массива strArray из типа данных string к другому типу данных, к примеру double, то это можно сделать нижеприведенным кодом:

// Преобразование всех элементов одномерного массива 
        // strArray из строкового типа в тип double.
        for (int i = 0; i < strArray.Length; i++)
            DataArray[i] = Convert.ToDouble(strArray[i]);

  • Обработка таблиц
  • Книги Excel
  • Массивы
  • Работа с файлами
  • Разное

Sub ПримерИспользования()
    ' задаём полный путь к обрабатываемому файлу
    ПутьКФайлу$ = ThisWorkbook.Path & "" & "Contract.XLS"
 
    Application.ScreenUpdating = False    '  отключаем обновление экрана
    arr = LoadArrayFromWorkbook(ПутьКФайлу$, "a2", 30)    ' загружаем данные

    ' выводим результаты в окно Immediate
    Debug.Print "Загружен массив размерами " & UBound(arr, 1) & _
                " строк на " & UBound(arr, 2) & " столбцов"
End Sub

Код функции LoadArrayFromWorkbook:

Function LoadArrayFromWorkbook(ByVal filename$, ByVal FirstCellAddress$, _
                               Optional ByVal ColumnsCount& = 0) As Variant
    ' Функция открывает в скрытом режиме файл filename$,
    ' загружает в двумерный массив информацию с первого листа файла
    ' (по высоте - начиная с ячейки FirstCellAddress$,
    '  и заканчивая последней заполненной ячейкой в этом столбце,
    '  по ширине - начиная с ячейки FirstCellAddress$, обрабатывается ColumnsCount& столбцов)
    ' Если переменная ColumnsCount& не задана - загружаются строки целиком
    ' После обработки файл filename$ закрывается без сохранения изменений

    ' Функция возвращает сформированный двумерный массив

    On Error Resume Next: Err.Clear
    Dim wb As Workbook, sh As Worksheet, ra As Range
    Set wb = GetObject(filename$)
    If wb Is Nothing Then Debug.Print "Не удалось загрузить файл " & filename$: Exit Function
    Set sh = wb.Worksheets(1)
    Set ra = sh.Range(sh.Range(FirstCellAddress$), _
                      sh.Range(FirstCellAddress$).EntireColumn.Cells(sh.Rows.Count).End(xlUp))
 
    If ra Is Nothing Then Debug.Print "Не удалось обработать таблицу из файла " & _
       filename$: Debug.Print "Первая ячейка: " & FirstCellAddress$: wb.Close False: Exit Function
 
    If ColumnsCount& = 0 Then ColumnsCount& = sh.Columns.Count - sh.Range(FirstCellAddress$).Column + 1
    Err.Clear: Set ra = ra.Resize(, ColumnsCount&)
    If Err Then Debug.Print "Не удалось расширить диапазон в файле " & _
       filename$: Debug.Print "Первая ячейка: " & FirstCellAddress$, _
                              "ширина: " & ColumnsCount&: wb.Close False: Exit Function
 
    LoadArrayFromWorkbook = ra.Value
    wb.Close False
End Function
  • 23355 просмотров

Не получается применить макрос? Не удаётся изменить код под свои нужды?

Оформите заказ у нас на сайте, не забыв прикрепить примеры файлов, и описать, что и как должно работать.

Довольно распространенная задача в программировании – загрузка данных в проект из внешнего файла. В отличие от загрузки из обычного текстового файла, загрузка из Excel, как и любого другого специального файла или подключение к базе данных, требует отдельного механизма реализации.

В данной статье рассматривается один из наиболее удобных способов работы с подгружаемыми из Excel данными. Значения всех ячеек страницы Excel вносятся в двумерный массив типа Variant. Затем с этим массивом уже можно работать любыми привычными способами.

В общем виде все сводится к подключению программы к файлу Excel, получению необходимого диапазона ячеек и присвоении вашему массиву значения заданного диапазона ячеек.

const
   xlCellTypeLastCell = $0000000B;
var
   ExcelApp, ExcelSheet: OLEVariant;
   MyMass: Variant;
   x, y: Integer;
begin
   // создание OLE-объекта Excel
   ExcelApp := CreateOleObject('Excel.Application');

   // открытие книги Excel
   ExcelApp.Workbooks.Open('C:my_excel.xls');

   // открытие листа книги
   ExcelSheet := ExcelApp.Workbooks[1].WorkSheets[1];

   // выделение последней задействованной ячейки на листе
   ExcelSheet.Cells.SpecialCells(xlCellTypeLastCell).Activate;

   // получение значений размера выбранного диапазона
   x := ExcelApp.ActiveCell.Row;
   y := ExcelApp.ActiveCell.Column;

   // присвоение массиву диапазона ячеек на листе
   MyMass := ExcelApp.Range['A1', ExcelApp.Cells.Item[X, Y]].Value;

   // закрытие книги и очистка переменных
   ExcelApp.Quit;
   ExcelApp := Unassigned;
   ExcelSheet := Unassigned;
end;

* Метод SpecialCells используется для выделения определенных ячеек на основании оценки их содержимого или других характеристик. Применяемое здесь значение параметра-константы xlCellTypeLastCell указывает методу выделить последнюю ячейку используемого диапазона, т.е. саму нижнюю правую ячейку в диапазоне, где введено хоть какое-то значение. Это позволяет копировать не все ячейки листа, а лишь диапазон, содержащий какие-либо данные.

Для использования команд работы с OLE-объектами для этого кода нужно добавить библиотеку:

uses
  ComObj;

После указанных операций данные введены в массив, из которого их можно перенести в компонент StringGrid или использовать их по своему усмотрению. Стоит заметить, что в полученном таким образом массиве данные индексы располагаются в следующем порядке: [номер строки, номер столбца]. Это видно из следующего примера вывода данных массива в компонент StringGrid.

// назначение размера StringGrid по размеру полученного диапазона ячеек
MyStringGrid.RowCount := x;
MyStringGrid.ColCount := y;

// заполнение таблицы StringGrid значениями массива
for x := 1 to MyStringGrid.ColCount do
  for y := 1 to MyStringGrid.RowCount do
      MyStringGrid.Cells[x-1, y-1] := MyMass[y, x];

Быстрая загрузка из EXCEL [1128]

[8] AdminITD — 2019-01-31 21:30:05

V82, Обычное приложение

  • Описание
  • Алгоритм выгрузки данных в двумерный массив
  • Файлы для скачивания
  • Комментарии
  • Описание

    Вложенная обработка демонстрирует один из самых быстрых способов выгрузки данных из EXCEL в таблицу значений 1С.


    Исходный EXCEL


    Данные в 1С

    Алгоритм выгрузки данных в двумерный массив

    &НаКлиенте
    Функция ПрочитатьЛистExcel(лпИмяФайла, лпНомерЛиста = 1, лпНомерПервойСтроки = 1, лпНомерПервойКолонки = 1) Экспорт
    	//Подключение к Excel
    	Попытка
    		лпExcel = Новый COMОбъект("Excel.Application");
    		лпExcel.Interactive	= False;
    		лпExcel.DisplayAlerts = False;
    		лпExcel.visible = False; 
    	Исключение
    		ВызватьИсключение "Возможно, Excel на компьютере не установлен. Необходимо выполнить установку/переустановку Excel." + Символы.ПС + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
    	КонецПопытки;     
    	
    	//Подключились удачно, открываем файл
    	лпExcel.Workbooks.Open(лпИмяФайла);
    	
    	//Открываем необходимый лист
    	лпExcel.Sheets(лпНомерЛиста).select();   
    	
    	//Получим количество строк и колонок.
    	//В разных версиях Excel получаются по-разному, поэтому сначала определим версию Excel
    	лпВерсия = Лев(лпExcel.Version, Найти(лпExcel.Version, ".") - 1);
    	
    	Если лпВерсия = "8" тогда
    		лпВсегоСтрок   = лпExcel.Cells.CurrentRegion.Rows.Count;
    		лпВсегоКолонок = Макс(лпExcel.Cells.CurrentRegion.Columns.Count, 13);
    	Иначе
    		лпВсегоСтрок   = лпExcel.Cells(1,1).SpecialCells(11).Row;
    		лпВсегоКолонок = лпExcel.Cells(1,1).SpecialCells(11).Column;   
    	КонецЕсли;
    	
    	лпОбластьДанных = лпExcel.Range(лпExcel.Cells(лпНомерПервойСтроки, лпНомерПервойКолонки), лпExcel.Cells(лпВсегоСтрок, лпВсегоКолонок));
    	
    	лпДанныеИзExcel = лпОбластьДанных.Value.Выгрузить(); //это двумерный массив
    	
    	лпExcel.Workbooks.Close();
    	лпExcel.quit();
    	
    	лпExcel = Неопределено;
    	
    	Возврат лпДанныеИзExcel;	
    КонецФункции

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

    ● Файлы для скачивания:

    для получения доступа требуется авторизация
    размер: 6.1 кб, скачиваний: 27.
    cодержимое архива: Загрузка из EXCEL.epf — 8,9 кб.

    Понравилась статья? Поделить с друзьями:
  • Загрузка excel в mysql php
  • Загрузить редактор текстов word
  • Загрузить редактор текста word
  • Загрузить программу word бесплатно на русском
  • Загрузить пакет совместимости для новой версии word