尝试从大括号中提取数据但不工作 [英] Trying to extract data from curly braces but not working

查看:133
本文介绍了尝试从大括号中提取数据但不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将C列中的大括号{}中的值进行同步,并将它们与列F中的用户标识相对照,如下所示。



例如。在电子邮件表单上





在新的表格上成为这个。



  Sub CopyConditional()
Dim wshS As工作表
Dim WhichName As String

设置wshS = ActiveWorkbook.Sheets(电子邮件)
WhereName =NewSheet

Const NameCol =C
Const FirstRow = 1

Dim LastRow As Long
Dim SrcRow As Long
Dim TrgRow As Long
Dim wshT As Worksheet
Dim cpt As String
Dim user As String
Dim computers()As String
Dim computer As String

On Error Resume Next
设置wshT = Worksheets whereName)
如果wshT不是,然后
设置wshT = Worksheets.Add(之后:= wshS)
wshT.Name = WhereName
结束如果
错误GoTo 0

如果wshT.Cells(1,NameCol).value =然后
TrgRo w = 1
Else
TrgRow = wshT.Cells(wshT.Rows.Count,NameCol).End(xlUp).Row + 1
End If

LastRow = wshS.Cells(wshS.Rows.Count,NameCol).End(xlUp).Row
对于SrcRow = FirstRow To LastRow
cpt = wshS.Range(C& SrcRow).value
user = wshS.Range(F& SrcRow).value

如果InStr(cpt,:)然后
cpt = Mid(cpt ,InStr(1,cpt,:)+ 1,Len(cpt))
End If

如果InStr(cpt,;)然后
computers = (cpt,;)
对于i = 0到UBound(计算机)
如果计算机(i)<> 然后
wshT.Range(A& TrgRow).value = user
wshT.Range(B& TrgRow).value = Mid(Left(computers(i),Len (电脑(i)) - 1),2)
TrgRow = TrgRow + 1
结束如果
下一个
Else
电脑= cpt
如果电脑<> 然后
wshT.Range(A& TrgRow).value = user
wshT.Range(B& TrgRow).value = Mid(Left(computer,Len(computer) - 1),2)
TrgRow = TrgRow + 1
如果
结束If

下一个SrcRow

End Sub

我使用上述代码解决了这个问题,但有三个棘手的问题: / p>

1)第一个大括号总是被复制,我如何省略这样的东西,像 {Computer1 code>计算机1





2)连接中有两台电脑,输出如下所示:





当它应该被分成两个不同的行,例如

 用户1 |电脑1 
用户1 |计算机2

3)如果在最后一个大括号之后有文本,其中包含文本。 {Computer1}; {Computer2};请求提交然后那个文本被添加为一个新行,我不想这样,我想要省略,例如





应该是:

 用户1 |电脑1 
用户1 |计算机2

我如何解决这些问题?

解决方案

尝试这样:

  Sub Collapse()
作为范围,cel As Range
Dim comps As Variant,comp As Variant,r As Variant,v As Variant
Dim d As Dictionary'~~>早期绑定,对于晚期绑定使用注释行
'Dim d As Object
Dim a As String

With Sheet1'~~>包含您的数据的工作表
设置uRng = .Range(F1,.Range(F& .Rows.Count).End(xlUp))
结束

设置d = CreateObject(Scripting.Dictionary)
对于每个cel在uRng
a =替换(cel.Offset(0,-3),{,
comps = Split(a,})
Debug.Print UBound(comps)
对于每个comp在comps
如果InStr(comp,Computer) <> 0 _
And Len(Trim(comp))< = 10 Then'~~>我假设max Comp#是99
如果不是.Exists(cel)然后
.Add cel,comp
Else
如果IsArray(.Item(cel))然后
r = .Item(cel)
ReDim Preserve r(UBound(r)+ 1)
r(UBound(r))= comp
.Item(cel)= r
Else
r = Array(.Item(cel),comp)
.Item(cel)= r
End If
End If
End If
Next
下一个
结束

对于每个v在d.Keys
与Sheet2'~~>如果IsArray(d.Item(v))然后
.Range(A& .Rows.Count).End(xlUp).Offset(1, 0)_
.Resize(UBound(d.Item(v))+ 1)= v
.Range(B& .Rows.Count).End(xlUp).Offset(1 ,0)_
.Resize(UBound(d.Item(v))+ 1)= Application.Transpose(d.Item(v))
Else
.Range(A & .Rows.Count).End(xlUp).Offset(1,0)= v
.Range(B& .Rows.Count).End(xlUp).Offset(1,0) = d.Item(v)
End If
End With
Next
设置d =无

End Sub

以上代码使用替换和拆分功能将您的字符串传递给数组。

  a =替换(cel.Offset(0,-3),{,})'~~>标准化分隔符
comps = Split(a,})'~~>使用标准分隔符分割

然后,使用用户键作为项目将信息传递到字典对象。 br>
我们使用 Instr和Len函数过滤传递到字典的项目

 如果InStr(comp,Computer)<> 0 _ 
And Len(修剪(comp))< = 10然后

我已经评论过,我假设你的最大电脑数是99.

否则你需要检查的任何长度改变10。

最后我们将字典信息返回到目标工作表。 br>
注意:如果您喜欢早期绑定,则需要添加对Microsoft Scripting Runtime的引用



结果:我尝试了一个小样本数据,我如何看到它在SS中。



所以假设你在Sheet1中有这个数据:



输出数据在Sheet2中,如下所示:


I need to sync up the values in the curly braces {} found in column C and put them against the user id in column F as seen below.

E.g. on the Emails sheet

becomes this on a new sheet

Sub CopyConditional()
Dim wshS As Worksheet
Dim WhichName As String

Set wshS = ActiveWorkbook.Sheets("Emails")
WhichName = "NewSheet"

Const NameCol = "C"
Const FirstRow = 1

Dim LastRow As Long
Dim SrcRow As Long
Dim TrgRow As Long
Dim wshT As Worksheet
Dim cpt As String
Dim user As String
Dim computers() As String
Dim computer As String

On Error Resume Next
Set wshT = Worksheets(WhichName)
If wshT Is Nothing Then
    Set wshT = Worksheets.Add(After:=wshS)
    wshT.Name = WhichName
End If
On Error GoTo 0

If wshT.Cells(1, NameCol).value = "" Then
    TrgRow = 1
Else
    TrgRow = wshT.Cells(wshT.Rows.Count, NameCol).End(xlUp).Row + 1
End If

LastRow = wshS.Cells(wshS.Rows.Count, NameCol).End(xlUp).Row
For SrcRow = FirstRow To LastRow
    cpt = wshS.Range("C" & SrcRow).value
    user = wshS.Range("F" & SrcRow).value

    If InStr(cpt, ":") Then
        cpt = Mid(cpt, InStr(1, cpt, ":") + 1, Len(cpt))
    End If

    If InStr(cpt, ";") Then
        computers = Split(cpt, ";")
        For i = 0 To UBound(computers)
            If computers(i) <> "" Then
                wshT.Range("A" & TrgRow).value = user
                wshT.Range("B" & TrgRow).value = Mid(Left(computers(i), Len(computers(i)) - 1), 2)
                TrgRow = TrgRow + 1
            End If
        Next
    Else
        computer = cpt
        If computer <> "" Then
            wshT.Range("A" & TrgRow).value = user
            wshT.Range("B" & TrgRow).value = Mid(Left(computer, Len(computer) - 1), 2)
            TrgRow = TrgRow + 1
        End If
    End If

Next SrcRow

End Sub

I managed to resolve it with the above code but there are 3 niggling issues:

1) The first curly brace is always copied, how do I omit this so something like {Computer1 looks like Computer 1

2) Where there are two computers in a row, then the output looks something like this:

when it should really be split into two different rows i.e.

User 1 | Computer 1
User 1 | Computer 2

3) If there is text after the last curly brace with text in it e.g. {Computer1};{Computer2};Request submitted then that text is added as a new row, I don't want this, I want it to be omitted e.g.

should just be:

User 1 | Computer 1
User 1 | Computer 2

How do I go about rectifying these issues?

解决方案

Try this:

Sub Collapse()
    Dim uRng As Range, cel As Range
    Dim comps As Variant, comp As Variant, r As Variant, v As Variant
    Dim d As Dictionary '~~> Early bind, for Late bind use commented line
    'Dim d As Object
    Dim a As String

    With Sheet1 '~~> Sheet that contains your data
        Set uRng = .Range("F1", .Range("F" & .Rows.Count).End(xlUp))
    End With

    Set d = CreateObject("Scripting.Dictionary")
    With d
        For Each cel In uRng
            a = Replace(cel.Offset(0, -3), "{", "}")
            comps = Split(a, "}")
            Debug.Print UBound(comps)
            For Each comp In comps
                If InStr(comp, "Computer") <> 0 _
                And Len(Trim(comp)) <= 10 Then '~~> I assumed max Comp# is 99
                    If Not .Exists(cel) Then
                        .Add cel, comp
                    Else
                        If IsArray(.Item(cel)) Then
                            r = .Item(cel)
                            ReDim Preserve r(UBound(r) + 1)
                            r(UBound(r)) = comp
                            .Item(cel) = r
                        Else
                            r = Array(.Item(cel), comp)
                            .Item(cel) = r
                        End If
                    End If
                End If
            Next
        Next
    End With

    For Each v In d.Keys
        With Sheet2 '~~> sheet you want to write your data to
            If IsArray(d.Item(v)) Then
                .Range("A" & .Rows.Count).End(xlUp).Offset(1, 0) _
                    .Resize(UBound(d.Item(v)) + 1) = v
                .Range("B" & .Rows.Count).End(xlUp).Offset(1, 0) _
                    .Resize(UBound(d.Item(v)) + 1) = Application.Transpose(d.Item(v))
            Else
                .Range("A" & .Rows.Count).End(xlUp).Offset(1, 0) = v
                .Range("B" & .Rows.Count).End(xlUp).Offset(1, 0) = d.Item(v)
            End If
        End With
    Next
    Set d = Nothing

End Sub

Above code uses Replace and Split Function to pass your string to array.

a = Replace(cel.Offset(0, -3), "{", "}") '~~> standardize delimiter
comps = Split(a, "}") '~~> split using standard delimiter

Then information are passed to dictionary object using User as key and computers as items.
We filter the items passed to dictionary using Instr and Len Function

If InStr(comp, "Computer") <> 0 _
And Len(Trim(comp)) <= 10 Then

As I've commented, I assumed your max computer number is 99.
Else change 10 to whatever length you need to check.
Finally we return the dictionary information to the target worksheet.
Note: You need to add reference to Microsoft Scripting Runtime if you prefer early bind

Result: I tried it on a small sample data patterned on how I see it in you SS.

So assuming you have this data in Sheet1:

Will output data in Sheet2 like this:

这篇关于尝试从大括号中提取数据但不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆