英文:
find students who failed each exam from two different sheets
问题
sheet1 EN
subject | S | N | Grade |
---|---|---|---|
EN | ben | ben | F |
EN | alex | smith | A |
EN | mark | will | F |
EN | snoop | dog | F |
sheet2 МА
subject | S | N | Grade |
---|---|---|---|
MA | ben | ben | F |
MA | mark | smith | A |
MA | snoop | dog | F |
sheet3 expected result
Surname | Name | status |
---|---|---|
ben | ben | failed |
snoop | dog | failed |
英文:
I am trying to find students who failed each exam from different sheets and write surname and name to new sheet3
sheet1 EN
subject | S | N | Grade |
---|---|---|---|
EN | ben | ben | F |
EN | alex | smith | A |
EN | mark | will | F |
EN | snoop | dog | F |
sheet2 МА
subject | S | N | Grade |
---|---|---|---|
MA | ben | ben | F |
MA | mark | smith | A |
MA | snoop | dog | F |
sheet3 expected result
Surname | Name | status |
---|---|---|
ben | ben | failed |
snoop | dog | failed |
答案1
得分: 2
这个方法可以工作,但使用了一个辅助列:
使用unique()需要控制len()以避免出现"N"。
使用match()的Index()是经典的方法。
最后是使用iferror()与match()两次结合使用,并使用and()。
英文:
Well, something like this works, but used a helper column:
The use of unique() needs the control of len() to avoid the "N" coming through.
Index() with match() is classic.
Last is iferror() with match() used twice and combined with and().
答案2
得分: 2
你可以按以下方式筛选sheet1,(1) 通过失败筛选,(2) 通过在sheet2中出现相同名称的失败筛选:
=FILTER(Sheet1!B2:D5, (Sheet1!D2:D5="F") * ISNUMBER(XMATCH(Sheet1!B2:B5&"|"&Sheet1!C2:C5, FILTER(Sheet2!B2:B4&"|"&Sheet2!C2:C4, Sheet2!D2:D4="F"))))
或者使用XLOOKUP:
=FILTER(Sheet1!B2:D5, (Sheet1!D2:D5="F") * (IFERROR(XLOOKUP(Sheet1!B2:B5&"|"&Sheet1!C2:C5, Sheet2!B2:B4&"|"&Sheet2!C2:C4, Sheet2!D2:D4), "")="F"))
英文:
You could filter sheet1 (1) by fail and (2) by a fail with the same name occurring in sheet2:
=FILTER(Sheet1!B2:D5,(Sheet1!D2:D5="F")*
ISNUMBER(XMATCH(Sheet1!B2:B5&"|"&Sheet1!C2:C5,
FILTER(Sheet2!B2:B4&"|"&Sheet2!C2:C4,Sheet2!D2:D4="F"))))
or using xlookup:
=FILTER(Sheet1!B2:D5,(Sheet1!D2:D5="F")*
(IFERROR(XLOOKUP(Sheet1!B2:B5&"|"&Sheet1!C2:C5,
Sheet2!B2:B4&"|"&Sheet2!C2:C4,Sheet2!D2:D4),"")="F"))
答案3
得分: 1
这种方法使用ADODB来查询工作表范围并将结果复制到目标范围(一个单元格)。该函数返回复制结果的范围。
Option Explicit
'---------------------------------------------------------------
' ra As Range> first range of data with headers
' rb As Range> first range of data with headers
' destination As Range> one cell anywhere to copy the results
'---------------------------------------------------------------
Public Function sqLFailedTwice(ra As Range, rb As Range, destination As Range) As Range
Dim connection As Object, recSet As Object, sql As String, tblA As String, tblB As String
Const PRO = " [", META = "] "
tblA = PRO & ra.Worksheet.Name & "$" & ra.Address(0, 0) & META
tblB = PRO & rb.Worksheet.Name & "$" & rb.Address(0, 0) & META
sql = "SELECT A.[S], A.[N], ""failed"" AS failed FROM " & tblA & "AS A INNER JOIN " & tblB & _
"AS B ON A.[S]=B.[S] AND A.[N]=B.[N] WHERE A.Grade=""F"" AND B.Grade=""F"" ORDER BY A.[S],A.[N]"
Set connection = CreateObject("ADODB.Connection")
With connection
.CursorLocation = 3
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = "Data Source=" & ThisWorkbook.Path & "\" & ThisWorkbook.Name & ";" & _
"Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1"";"
.Open
Set recSet = .Execute(sql)
End With
'if found records copy them and return the range where copied
If recSet.recordCount > 0 Then
Call destination.CopyFromRecordset(recSet)
Set sqLFailedTwice = destination.Resize(recSet.recordCount, 3)
End If
recSet.Close
connection.Close
Set recSet = Nothing
Set connection = Nothing
End Function
Sub execSql()
Dim rslt As Range
'WE CAN READ FROM ANY SHEET/RANGE AND COPY TO ANY SHEET/RANGE
Set rslt = sqLFailedTwice(SHEET08.Range("P1:S5"), _
SHEET09.Range("P1:S4"), _
SHEET10.Range("G2"))
Debug.Print rslt.Address
End Sub
英文:
This way uses ADODB to query the sheet ranges and copy the result at destination range (one cell). The function returns the range where copied the results.
Option Explicit
'---------------------------------------------------------------
' ra As Range> first range of data with headers
' rb As Range> first range of data with headers
' destination As Range> one cell anywhere to copy the results
'---------------------------------------------------------------
Public Function sqLFailedTwice(ra As Range, rb As Range, destination As Range) As Range
Dim connection As Object, recSet As Object, sql As String, tblA As String, tblB As String
Const PRO = " [", META = "] "
tblA = PRO & ra.Worksheet.Name & "$" & ra.Address(0, 0) & META
tblB = PRO & rb.Worksheet.Name & "$" & rb.Address(0, 0) & META
sql = "SELECT A.[S], A.[N], ""failed"" AS failed FROM " & tblA & "AS A INNER JOIN " & tblB & _
"AS B ON A.[S]=B.[S] AND A.[N]=B.[N] WHERE A.Grade=""F"" AND B.Grade=""F"" ORDER BY A.[S],A.[N]"
Set connection = CreateObject("ADODB.Connection")
With connection
.CursorLocation = 3
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = "Data Source=" & ThisWorkbook.Path & "\" & ThisWorkbook.Name & ";" & _
"Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1"";"
.Open
Set recSet = .Execute(sql)
End With
'if found records copy them and return the range where copied
If recSet.recordCount > 0 Then
Call destination.CopyFromRecordset(recSet)
Set sqLFailedTwice = destination.Resize(recSet.recordCount, 3)
End If
recSet.Close
connection.Close
Set recSet = Nothing
Set connection = Nothing
End Function
Sub execSql()
Dim rslt As Range
'WE CAN READ FROM ANY SHEET/RANGE AND COPY TO ANY SHEET/RANGE
Set rslt = sqLFailedTwice(SHEET08.Range("P1:S5"), _
SHEET09.Range("P1:S4"), _
SHEET10.Range("G2"))
Debug.Print rslt.Address
End Sub
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论