从Excel或.csv数据集

时间:2017-08-30 19:15:29

标签: excel excel-vba csv excel-formula powerbi vba

使用包含在单个列中的不完整数字列表(例如,3,7,9,10,11,12,17,22,23,24,28等等)的一些数据集。

希望将它们编译成一个更加类似于3,7,9-12,17,22-24,28等的连字范围的集合......

在一个区域内输入位置数据,这样数据就不需要与任何其他单元格相关联,只需要将总数据集从数千个单独的值减少到希望几百个数值范围

Example data set

我们假设有一个简单的选项,但在Excel或Power BI中没有运气。

谢谢,一切顺利,

4 个答案:

答案 0 :(得分:0)

我相信其他用户会有更优雅的答案。如果你只是需要一个快速的黑客,这将做。第一排需要一些特殊处理。

enter image description here

enter image description here

以下是第2行的公式:

B2:=IF(A2-1=A1,"",A2)

C2:=IF(AND(A2+1=A3,A2-1<>A1),"-","")

D2:=IF(A2+1=A3,"",A2)

E2:=IF(C2="-",INDEX(D2:D$11,MATCH(TRUE,ISNUMBER(D2:D$11),0)),"") *

*这使用数组公式,所以在输入后你需要 Ctrl Shift 输入。您还可以更改D$11以引用您正在使用的底行。

F2:=CONCAT(B2,C2,E2)

答案 1 :(得分:0)

sub bellow将对主列(A,Sheet1)进行排序,并在新列中生成结果

Option Explicit
Public Sub CreateSets()
    Dim arr As Variant, workCol As Long, workSet As Range
    Dim r As Long, rCount As Long, lastVal As Long, ub As Long
    Set workSet = Sheet1.UsedRange.Columns(1)           '<-- Update Sheet1 and Col
    SortCol workSet             'Sort main column, and add a new column to its right
    arr = workSet.Resize(workSet.Rows.Count, 2)         'Copy the 2 columns to array
    ub = UBound(arr)
    For r = 1 To ub
        If r = ub Then
            arr(r, 2) = arr(r, 1)
            Exit For
        End If
        If arr(r + 1, 1) <> arr(r, 1) Then          'Ignore dupes
            lastVal = arr(r, 1)
            rCount = r
            If rCount < ub Then
                Do
                    If arr(rCount + 1, 1) = arr(rCount, 1) + 1 Then
                        lastVal = arr(rCount + 1, 1)
                        rCount = rCount + 1
                        If rCount = ub Then Exit Do
                    End If
                Loop While arr(rCount + 1, 1) = arr(rCount, 1) + 1
            End If
            arr(r, 2) = arr(r, 1)
            If lastVal <> arr(r, 1) Then            'If a set was found, skip it
                arr(r, 2) = arr(r, 2) & "-" & lastVal
                r = rCount
            End If
        End If
    Next
    workSet.Offset(, 1).NumberFormat = "@"          'Change 2nd column to Text format
    workSet.Resize(workSet.Rows.Count, 2) = arr     'Copy results back to range
End Sub
Private Sub SortCol(ByRef oneColRng As Range)
    Dim ws As Worksheet

    If Not oneColRng Is Nothing Then
        Set ws = oneColRng.Parent
        Application.ScreenUpdating = False
        With ws.Sort
            .SortFields.Clear
            .SortFields.Add Key:=oneColRng.Cells(1, 1), _
                            SortOn:=xlSortOnValues, _
                            Order:=xlAscending
            .SetRange oneColRng
            .Header = xlNo           '<-- Change this to "xlYes" if there are Headers
            .MatchCase = False
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
        End With
        With oneColRng.Offset(, 1)
            .Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
            .AutoFit
        End With
        Application.ScreenUpdating = True
    End If
End Sub

Sets - 1 of 2 Sets - 2 of 2

答案 2 :(得分:0)

我会用awk这样的事情来做:

awk 'NR==1   {b=e=$1; next}         # first line, set begin and end of current range, move to next line
     $1==e+1 {e=$1; next}           # if this line contiguous with previous, update range end and move on
             {print b,e; b=e=$1}    # not contiguous, print last range, start new range
     END     {print b,e}' data.csv

或者,同样但是作为一个班轮:

awk 'NR==1{b=e=$1;next} $1==e+1{e=$1;next} {print b,e;b=e=$1} END{print b,e}' data.csv

示例输出

3 3
7 7
9 12
17 17
22 24
28 28
3 3
7 7
9 12
17 17
22 24
28 28

可以重新格式化输出以更符合您的需求,或者您可以再次通过awk运行它:

awk 'NR==1{b=e=$1;next} $1==e+1{e=$1;next} {print b,e;b=e=$1} END{print b,e}' data.csv |
   awk '{x=$1; if($1!=$2)x=x "-" $2;print x}'

<强>输出

3
7
9-12
17
22-24
28

答案 3 :(得分:0)

如果您想使用Power Query进行尝试,可以执行以下操作:

从您的价值表开始:

enter image description here

单击&#34;添加列&#34;添加索引列;选项卡,然后&#34;索引列&#34;

enter image description here

单击&#34;添加列&#34;添加另一列;选项卡,然后&#34;自定义列&#34;并在&#34;自定义列公式&#34中输入try if Number.From(#"Added Index"{[Index]}[Values]) = Number.From(#"Added Index"{[Index]+1}[Values])-1 then Text.From(Number.From(#"Added Index"{[Index]}[Values])) else Text.From(Number.From(#"Added Index"{[Index]}[Values])) & "-" & Text.From(Number.From(#"Added Index"{[Index]+1}[Values])-1) otherwise Text.From(Number.From(#"Added Index"{[Index]}[Values]));弹出窗口的方框。

enter image description here

你会得到这个:

enter image description here

这是查询代码:

let
Source = Table1,
#"Added Index" = Table.AddIndexColumn(Source, "Index", 0, 1),
#"Added Custom1" = Table.AddColumn(#"Added Index", "NewValues", each 
    try 
        if Number.From(#"Added Index"{[Index]}[Values]) = Number.From(#"Added Index"{[Index]+1}[Values])-1 
        then Text.From(Number.From(#"Added Index"{[Index]}[Values]))
        else Text.From(Number.From(#"Added Index"{[Index]}[Values])) & "-" & Text.From(Number.From(#"Added Index"{[Index]+1}[Values])-1) 
    otherwise Text.From(Number.From(#"Added Index"{[Index]}[Values])))
in
#"Added Custom1"

我使用Number.FromText.From来强制使用+-&所需的正确类型。