集合到数组然后到范围

时间:2019-05-04 21:31:16

标签: arrays excel vba collections

我在Excel中有2d矩阵,其中填充了数字和零。我需要列出矩阵的每一行中的数字而不能有空格(这里没有零),这就是为什么要将它们添加到集合中的原因。比起我在Stackoverlow上找到的函数,我将集合转换为数组时需要将行写回到Excel。该解决方案几乎可以正常工作,除非在矩阵中只有1个数字的情况下,用相同值的数字填充整行。该问题似乎是在将值写回到单元格期间发生的。其次,如何去除结果中的#N / D?屏幕和代码随附,谢谢。

https://imgur.com/a/aP16DE1

Option Explicit
Public Function CollectionToArray(myCol As Collection) As Variant

Dim result  As Variant
Dim cnt     As Long

ReDim result(myCol.Count - 1)

For cnt = 0 To myCol.Count - 1
result(cnt) = myCol(cnt + 1)
Next cnt

CollectionToArray = result

End Function

Public Sub TestMe()

Dim cell, k As Variant
Dim i  As Integer
Dim myCol As New Collection
Dim grKol, Destination As Range

Set grKol = Range("D4:BA4")
Set Destination = Range("D20:R20")


For i = 1 To 50
If Application.WorksheetFunction.Sum(grKol.Offset(i - 1, 0)) = 0 Then 
Exit For
For Each cell In grKol.Offset(i - 1, 0)
    If cell > 0 Then
    myCol.Add cell
    End If
Next cell
k = CollectionToArray(myCol)
Destination.Offset(i, 0) = k
Set myCol = Nothing
Next i


End Sub

2 个答案:

答案 0 :(得分:1)

一些建议的更改:

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class FileUtil {

private static final String FILE_NAME = "chatIds.txt";

public static boolean writeChatId(long chatId) {
    try {
        Path path = Paths.get(FILE_NAME);

        List<Long> adminChatIds = getChatIds();
        if (adminChatIds.contains(chatId)) return true;

        Files.write(path, (String.valueOf(chatId) + System.lineSeparator()).getBytes(), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
    } catch (IOException e) {
        return false;
    }
    return true;
}

public static List<Long> getChatIds() {
    try {
        Path path = Paths.get(FILE_NAME);
        List<Long> result = new ArrayList<>();

        for (String line : Files.readAllLines(path)) {
            result.add(Long.valueOf(line));
        }
        return result;
    } catch (Exception e) {
        return Collections.emptyList();
    }
}

}

答案 1 :(得分:1)

我不确定您是否以最有效的方式执行此操作。使用For Each循环而不是按索引循环遍历一个集合要快得多,并且一次写完所有输出可能会更好。

实现上述目标的骨架代码如下所示:

Dim data As Variant
Dim i As Long, j As Long, maxDim As Long
Dim rowItems As Collection, colItems As Collection
Dim output() As Variant

'Read data into an array.
data = Sheet1.Range("D4:R18").Value

'Loop through each item to populate the collections.
Set rowItems = New Collection
For i = 1 To UBound(data, 1)
    Set colItems = New Collection
    For j = 1 To UBound(data, 2)
        'Add item if it isn't a 0.
        If data(i, j) <> 0 Then colItems.Add data(i, j)
    Next
    'Add the items to the row collection if
    'it contains 1 or more items.
    If colItems.Count > 0 Then
        rowItems.Add colItems
        'Keep a note of the max number of items
        'to resize the output array.
        If colItems.Count > maxDim Then maxDim = colItems.Count
    End If
Next

'Set the output array size.
ReDim output(1 To rowItems.Count, 1 To maxDim)

'Populate the array.
i = 1
For Each colItems In rowItems
    j = 1
    For Each data In colItems
        output(i, j) = data
        j = j + 1
    Next
    i = i + 1
Next

'Write the output array to sheet.
Sheet1.Range("D21").Resize(UBound(output, 1), UBound(output, 2)).Value = output