问:
vba to list down changes on sheet3 from sheet1 and sheet2
So I have 2 sheets with different no. of rows due to the changes between the two and I am trying to list them down on sheet3. If they are not on either sheets then I will just place the value as 0 when comparing against the sheets that the identifier is found. I am looping through columns and rows on one sheet and is having problem locating the correct identifier since the no. of rows are different due to the changes, meaning I pull the wrong values from the wrong row.

This is what I have wrote so far, not sure if anyone can give a hand.

this is just column and row loop

```<code>
Dim wb As Workbook
Dim sht1 As Worksheet, sht2 As Worksheet, sht3 As Worksheet
Dim lastrow1 As Integer, lastrow2 As Integer, i As Integer, j As Integer, k As Integer, l As Integer, M As String, rg As Range
Set wb = ThisWorkbook
Set sht1 = wb.Sheets("sheet1")
Set sht2 = wb.Sheets("sheet2")
Set sht3 = wb.Sheets("List of Changes")
lastrow1 = sht1.Cells(rows.Count, "C").End(xlUp).Row
lastrow2 = sht2.Cells(rows.Count, "C").End(xlUp).Row
k = 2
l = 3

sht3.Range("M1:T1") = Array("Seq", "Grade ID", "Item", "UOM", "Issue 1", "Issue 2", "Change", "Remark")
sht3.Range("M1:T1").Font.Bold = True

For j = 8 To 17
    For i = 2 To lastrow2
    Set rg = sht1.Range("E2:E" & lastrow1).Find(sht2.Range("E" & i))
            If rg Is Nothing Then
                If sht2.Cells(i, j) = 0 Then

                Else
                sht3.Range("N" & k).Value = sht2.Cells(i, 5).Value
                sht3.Range("O" & k).Value = sht2.Cells(1, j).Value
                M = sht3.Range("O" & k).Value
                sht3.Range("P" & k).Value = Right(M, 3)
                sht3.Range("O" & k).Value = Left(M, 10)
                sht3.Range("Q" & k).Value = 0
                sht3.Range("R" & k).Value = sht2.Cells(i, j).Value
                sht3.Range("S" & k).Value = sht2.Cells(i, j).Value - sht3.Range("Q" & k).Value
                k = k + 2
                End If

            ElseIf sht2.Cells(i, 5) <> sht1.Cells(i, 5) Then

            ElseIf sht2.Cells(i, 5) = sht1.Cells(i, 5) Then
                If sht2.Cells(i, j) = sht1.Cells(i, j) Then

                Else
                sht3.Range("N" & k).Value = sht2.Cells(i, 5).Value
                sht3.Range("O" & k).Value = sht2.Cells(1, j).Value
                M = sht3.Range("O" & k).Value
                sht3.Range("P" & k).Value = Right(M, 3)
                sht3.Range("O" & k).Value = Left(M, 10)
                sht3.Range("Q" & k).Value = sht1.Cells(i, j).Value
                sht3.Range("R" & k).Value = sht2.Cells(i, j).Value
                sht3.Range("S" & k).Value = sht2.Cells(i, j).Value - sht3.Range("Q" & k).Value
                k = k + 2
                End If

            End If

    Next i
Next j

For j = 18 To 27
    For i = 2 To lastrow2

    Set rg = sht1.Range("E2:E" & lastrow1).Find(sht2.Range("E" & i))
            If rg Is Nothing Then
                If sht2.Cells(i, j) = 0 Then

                Else
                sht3.Range("N" & l).Value = sht2.Cells(i, 5).Value
                sht3.Range("O" & l).Value = sht2.Cells(1, j).Value
                M = sht3.Range("O" & l).Value
                sht3.Range("P" & l).Value = Right(M, 2)
                sht3.Range("O" & l).Value = Left(M, 10)
                sht3.Range("Q" & l).Value = 0
                sht3.Range("R" & l).Value = sht2.Cells(i, j).Value
                sht3.Range("S" & l).Value = sht2.Cells(i, j).Value - sht3.Range("Q" & l).Value
                l = l + 2
                End If

            ElseIf sht2.Cells(i, 5) <> sht1.Cells(i, 5) Then

            ElseIf sht2.Cells(i, 5) = sht1.Cells(i, 5) Then
                If sht2.Cells(i, j) = sht1.Cells(i, j) Then

                Else
                sht3.Range("N" & l).Value = sht2.Cells(i, 5).Value
                sht3.Range("O" & l).Value = sht2.Cells(1, j).Value
                M = sht3.Range("O" & l).Value
                sht3.Range("P" & l).Value = Right(M, 2)
                sht3.Range("O" & l).Value = Left(M, 10)
                sht3.Range("Q" & l).Value = sht1.Cells(i, j).Value
                sht3.Range("R" & l).Value = sht2.Cells(i, j).Value
                sht3.Range("S" & l).Value = sht2.Cells(i, j).Value - sht3.Range("Q" & l).Value
                l = l + 2
                End If
            End If

    Next i
Next j

End Sub
</code>```

This one loops to sheet2 as well with 3 loops

```<code>Sub listofchangesfail()

Dim wb As Workbook
Dim sht1 As Worksheet, sht2 As Worksheet, sht3 As Worksheet
Dim lastrow1 As Integer, lastrow2, lastrow3, lastrow4 As Integer, h, x, i As Integer, j As Integer, k As Integer, l As Integer, M As String, rg As Range
Set wb = ThisWorkbook
Set sht1 = wb.Sheets("sheet1")
Set sht2 = wb.Sheets("sheet2")
Set sht3 = wb.Sheets("List of Changes")
lastrow1 = sht1.Cells(rows.Count, "C").End(xlUp).Row
lastrow2 = sht2.Cells(rows.Count, "C").End(xlUp).Row
k = 2
l = 3

sht3.Range("M1:T1") = Array("Seq", "Grade ID", "Item", "UOM", "Issue 1", "Issue 2", "Change", "Remark")
sht3.Range("M1:T1").Font.Bold = True

For j = 8 To 17
    For i = 2 To lastrow2
        For h = 2 To lastrow1
    Set rg = sht1.Range("E2:E" & lastrow1).Find(sht2.Range("E" & i))
            If rg Is Nothing Then
                If sht2.Cells(i, j) = 0 Then

                Else
                sht3.Range("N" & k).Value = sht2.Cells(i, 5).Value
                sht3.Range("O" & k).Value = sht2.Cells(1, j).Value
                M = sht3.Range("O" & k).Value
                sht3.Range("P" & k).Value = Right(M, 3)
                sht3.Range("O" & k).Value = Left(M, 10)
                sht3.Range("Q" & k).Value = 0
                sht3.Range("R" & k).Value = sht2.Cells(i, j).Value
                sht3.Range("S" & k).Value = sht2.Cells(i, j).Value - sht3.Range("Q" & k).Value
                k = k + 2
                End If

            ElseIf sht2.Cells(i, 5) <> sht1.Cells(h, 5) Then

            ElseIf sht2.Cells(i, 5) = sht1.Cells(h, 5) Then
                If sht2.Cells(i, j) = sht1.Cells(h, j) Then

                Else
                sht3.Range("N" & k).Value = sht2.Cells(i, 5).Value
                sht3.Range("O" & k).Value = sht2.Cells(1, j).Value
                M = sht3.Range("O" & k).Value
                sht3.Range("P" & k).Value = Right(M, 3)
                sht3.Range("O" & k).Value = Left(M, 10)
                sht3.Range("Q" & k).Value = sht1.Cells(h, j).Value
                sht3.Range("R" & k).Value = sht2.Cells(i, j).Value
                sht3.Range("S" & k).Value = sht2.Cells(i, j).Value - sht3.Range("Q" & k).Value
                k = k + 2
                End If

            End If
        Next h
    Next i
Next j

For j = 18 To 27
    For i = 2 To lastrow2
        For h = 2 To lastrow1
    Set rg = sht1.Range("E2:E" & lastrow1).Find(sht2.Range("E" & i))
            If rg Is Nothing Then
                If sht2.Cells(i, j) = 0 Then

                Else
                sht3.Range("N" & l).Value = sht2.Cells(i, 5).Value
                sht3.Range("O" & l).Value = sht2.Cells(1, j).Value
                M = sht3.Range("O" & l).Value
                sht3.Range("P" & l).Value = Right(M, 2)
                sht3.Range("O" & l).Value = Left(M, 10)
                sht3.Range("Q" & l).Value = 0
                sht3.Range("R" & l).Value = sht2.Cells(i, j).Value
                sht3.Range("S" & l).Value = sht2.Cells(i, j).Value - sht3.Range("Q" & l).Value
                l = l + 2
                End If

            ElseIf sht2.Cells(i, 5) <> sht1.Cells(h, 5) Then

            ElseIf sht2.Cells(i, 5) = sht1.Cells(h, 5) Then
                If sht2.Cells(i, j) = sht1.Cells(h, j) Then

                Else
                sht3.Range("N" & l).Value = sht2.Cells(i, 5).Value
                sht3.Range("O" & l).Value = sht2.Cells(1, j).Value
                M = sht3.Range("O" & l).Value
                sht3.Range("P" & l).Value = Right(M, 2)
                sht3.Range("O" & l).Value = Left(M, 10)
                sht3.Range("Q" & l).Value = sht1.Cells(h, j).Value
                sht3.Range("R" & l).Value = sht2.Cells(i, j).Value
                sht3.Range("S" & l).Value = sht2.Cells(i, j).Value - sht3.Range("Q" & l).Value
                l = l + 2
                End If
            End If

        Next h
    Next i
Next j

End Sub
</code>```

答:
posting my answer as below</p>
```<code>Sub listofchanges()

   Dim wb As Workbook
   Dim ws1, ws2, ws3 As Worksheet
   Dim iLastRow1, iLastRow2, r1, r2, r3, c, x As Long
   Dim i, j As Integer
   Dim dict As Object, k, key, s As String
   Set dict = CreateObject("Scripting.Dictionary")

   ' prepare output sheet
   Set wb = ThisWorkbook
   Set ws3 = wb.Sheets("List of Changes")
   ws3.Cells.Clear
   With ws3.Range("M1:T1")
        .Value2 = Array("Seq", "Grade ID", "Item", "UOM", _
                        "Issue 1", "Issue 2", "Change", "Remark")
        .Font.Bold = True
   End With

   ' Scan sheet 1
   Set ws1 = wb.Sheets("iss1")
   iLastRow1 = ws1.Cells(rows.Count, "E").End(xlUp).Row

   ' build dictionary from sheet 1 key on column E
   For r1 = 2 To iLastRow1
       key = Trim(ws1.Cells(r1, "E"))
       If Len(key) > 0 Then
          If dict.exists(key) Then
              MsgBox "Duplicate key " & key, vbCritical, ws1.Name & " Row " & r1
              Exit Sub
          Else
              dict.Add key, r1
          End If
       End If
   Next

    ' Scan sheet 2, compare with sheet 1 and output to sheet 3
    Set ws2 = wb.Sheets("iss2")
    r3 = 2
    iLastRow2 = ws2.Cells(rows.Count, "E").End(xlUp).Row
    For i = 8 To 17
        If i = 13 Or i = 15 Or i = 16 Or i = 17 Then
        GoTo here1
        Else
        For r2 = 2 To iLastRow2
            key = Trim(ws2.Cells(r2, "E"))
            If Len(key) > 0 Then
                ' compare with iss2
                If dict.exists(key) Then
                    r1 = dict(key)
'                    If i = 17 Then dict.Remove key ' last loop and remove from dict
                Else
                    r1 = 0
                End If

                    s = ws2.Cells(1, i) ' column header
                    y = Len(s) - 7 'crop away unwanted words
                    With ws3
                        .Cells(r3, "N") = key
                        .Cells(r3, "O") = Left(s, y)
                        .Cells(r3, "P") = Right(s, 3)
                        If r1 = 0 Then
                            .Cells(r3, "Q") = 0
                        Else
                            .Cells(r3, "Q") = ws1.Cells(r1, i) ' this is wrong
                        End If
                        .Cells(r3, "R") = ws2.Cells(r2, i).Value2
                        .Cells(r3, "S").FormulaR1C1 = "=RC[-1] - RC[-2]" ' Q-R
                    End With
                    r3 = r3 + 2
           End If
        Next
        End If
here1:
    Next

    r3 = 3 'MT
    For i = 18 To 27
        If i = 23 Or i = 25 Or i = 26 Or i = 27 Then
        GoTo there1
        Else
        For r2 = 2 To iLastRow2
            key = Trim(ws2.Cells(r2, "E"))
            If Len(key) > 0 Then
                ' compare with iss2
                If dict.exists(key) Then
                    r1 = dict(key)
                    If i = 24 Then dict.Remove key ' last loop and remove from dict
                Else
                    r1 = 0
                End If

                    s = ws2.Cells(1, i) ' column header
                    y = Len(s) - 6 'crop away unwanted words
                    With ws3
                        .Cells(r3, "N") = key
                        .Cells(r3, "O") = Left(s, y)
                        .Cells(r3, "P") = Right(s, 2)
                        If r1 = 0 Then
                            .Cells(r3, "Q") = 0
                        Else
                            .Cells(r3, "Q") = ws1.Cells(r1, i) 'this is wrong
                        End If
                        .Cells(r3, "R") = ws2.Cells(r2, i).Value2
                        .Cells(r3, "S").FormulaR1C1 = "=RC[-1] - RC[-2]" ' Q-R
                    End With
                    r3 = r3 + 2
           End If
        Next
        End If
there1:
    Next
r4 = r3 - 2 + 1
r3 = r4

    ' add remaining keys from iss2 not in iss3
    For i = 8 To 17 'k15
        If i = 13 Or i = 15 Or i = 16 Or i = 17 Then
        GoTo here2
        Else
        For Each k In dict.keys
            r1 = dict(k)

                s = ws2.Cells(1, i) ' column header
                y = Len(s) - 7 'crop away unwanted words
                With ws3
                    .Cells(r3, "N") = CStr(k)
                    .Cells(r3, "O") = Left(s, y)
                    .Cells(r3, "P") = Right(s, 3)
                    If r1 = 0 Then
                        .Cells(r3, "Q") = 0
                    Else
                        .Cells(r3, "Q") = ws1.Cells(r1, i)
                    End If
'                    .Cells(r3, "R") = ws2.Cells(r1, i).Value2
'                    .Cells(r3, "Q") = ws1.Cells(r1, i)
                    .Cells(r3, "R") = 0    ' no sheet 2 value bcos not remove from dict, not in iss3
                    .Cells(r3, "S").FormulaR1C1 = "=RC[-1] - RC[-2]" ' Q-R

                End With
                r3 = r3 + 2
        Next
        End If
here2:
    Next

    r4 = r4 + 1
    r3 = r4
    For i = 18 To 27 'MT
        If i = 23 Or i = 25 Or i = 26 Or i = 27 Then
        GoTo there2
        Else
        For Each k In dict.keys
            r1 = dict(k)

                s = ws2.Cells(1, i) ' column header
                y = Len(s) - 6 'crop away unwanted words
                With ws3
                    .Cells(r3, "N") = CStr(k)
                    .Cells(r3, "O") = Left(s, y)
                    .Cells(r3, "P") = Right(s, 2)
                    If r1 = 0 Then
                        .Cells(r3, "Q") = 0
                    Else
                        .Cells(r3, "Q") = ws1.Cells(r1, i)
                    End If
'                    .Cells(r3, "R") = ws2.Cells(r1, i).Value2
'                    .Cells(r3, "Q") = ws1.Cells(r1, i)
                    .Cells(r3, "R") = 0    ' no sheet 2 value bcos not remove from dict, not in iss3
                    .Cells(r3, "S").FormulaR1C1 = "=RC[-1] - RC[-2]" ' Q-R

                End With
                r3 = r3 + 2
        Next
        End If
there2:
    Next

    MsgBox "OK", vbInformation
End Sub
</code>```

Body:
So I have 2 sheets with different no. of rows due to the changes between the two and I am trying to list them down on sheet3. If they are not on either sheets then I will just place the value as 0 when comparing against the sheets that the identifier is found. I am looping through columns and rows on one sheet and is having problem locating the correct identifier since the no. of rows are different due to the changes, meaning I pull the wrong values from the wrong row.

This is what I have wrote so far, not sure if anyone can give a hand.

this is just column and row loop

Dim wb As Workbook
Dim sht1 As Worksheet, sht2 As Worksheet, sht3 As Worksheet
Dim lastrow1 As Integer, lastrow2 As Integer, i As Integer, j As Integer, k As Integer, l As Integer, M As String, rg As Range
Set wb = ThisWorkbook
Set sht1 = wb.Sheets("sheet1")
Set sht2 = wb.Sheets("sheet2")
Set sht3 = wb.Sheets("List of Changes")
lastrow1 = sht1.Cells(rows.Count, "C").End(xlUp).Row
lastrow2 = sht2.Cells(rows.Count, "C").End(xlUp).Row
k = 2
l = 3

sht3.Range("M1:T1") = Array("Seq", "Grade ID", "Item", "UOM", "Issue 1", "Issue 2", "Change", "Remark")
sht3.Range("M1:T1").Font.Bold = True

For j = 8 To 17
    For i = 2 To lastrow2
    Set rg = sht1.Range("E2:E" & lastrow1).Find(sht2.Range("E" & i))
            If rg Is Nothing Then
                If sht2.Cells(i, j) = 0 Then

                Else
                sht3.Range("N" & k).Value = sht2.Cells(i, 5).Value
                sht3.Range("O" & k).Value = sht2.Cells(1, j).Value
                M = sht3.Range("O" & k).Value
                sht3.Range("P" & k).Value = Right(M, 3)
                sht3.Range("O" & k).Value = Left(M, 10)
                sht3.Range("Q" & k).Value = 0
                sht3.Range("R" & k).Value = sht2.Cells(i, j).Value
                sht3.Range("S" & k).Value = sht2.Cells(i, j).Value - sht3.Range("Q" & k).Value
                k = k + 2
                End If

            ElseIf sht2.Cells(i, 5) <> sht1.Cells(i, 5) Then

            ElseIf sht2.Cells(i, 5) = sht1.Cells(i, 5) Then
                If sht2.Cells(i, j) = sht1.Cells(i, j) Then

                Else
                sht3.Range("N" & k).Value = sht2.Cells(i, 5).Value
                sht3.Range("O" & k).Value = sht2.Cells(1, j).Value
                M = sht3.Range("O" & k).Value
                sht3.Range("P" & k).Value = Right(M, 3)
                sht3.Range("O" & k).Value = Left(M, 10)
                sht3.Range("Q" & k).Value = sht1.Cells(i, j).Value
                sht3.Range("R" & k).Value = sht2.Cells(i, j).Value
                sht3.Range("S" & k).Value = sht2.Cells(i, j).Value - sht3.Range("Q" & k).Value
                k = k + 2
                End If

            End If

    Next i
Next j

For j = 18 To 27
    For i = 2 To lastrow2

    Set rg = sht1.Range("E2:E" & lastrow1).Find(sht2.Range("E" & i))
            If rg Is Nothing Then
                If sht2.Cells(i, j) = 0 Then

                Else
                sht3.Range("N" & l).Value = sht2.Cells(i, 5).Value
                sht3.Range("O" & l).Value = sht2.Cells(1, j).Value
                M = sht3.Range("O" & l).Value
                sht3.Range("P" & l).Value = Right(M, 2)
                sht3.Range("O" & l).Value = Left(M, 10)
                sht3.Range("Q" & l).Value = 0
                sht3.Range("R" & l).Value = sht2.Cells(i, j).Value
                sht3.Range("S" & l).Value = sht2.Cells(i, j).Value - sht3.Range("Q" & l).Value
                l = l + 2
                End If

            ElseIf sht2.Cells(i, 5) <> sht1.Cells(i, 5) Then

            ElseIf sht2.Cells(i, 5) = sht1.Cells(i, 5) Then
                If sht2.Cells(i, j) = sht1.Cells(i, j) Then

                Else
                sht3.Range("N" & l).Value = sht2.Cells(i, 5).Value
                sht3.Range("O" & l).Value = sht2.Cells(1, j).Value
                M = sht3.Range("O" & l).Value
                sht3.Range("P" & l).Value = Right(M, 2)
                sht3.Range("O" & l).Value = Left(M, 10)
                sht3.Range("Q" & l).Value = sht1.Cells(i, j).Value
                sht3.Range("R" & l).Value = sht2.Cells(i, j).Value
                sht3.Range("S" & l).Value = sht2.Cells(i, j).Value - sht3.Range("Q" & l).Value
                l = l + 2
                End If
            End If

    Next i
Next j

End Sub

This one loops to sheet2 as well with 3 loops

Sub listofchangesfail()

Dim wb As Workbook
Dim sht1 As Worksheet, sht2 As Worksheet, sht3 As Worksheet
Dim lastrow1 As Integer, lastrow2, lastrow3, lastrow4 As Integer, h, x, i As Integer, j As Integer, k As Integer, l As Integer, M As String, rg As Range
Set wb = ThisWorkbook
Set sht1 = wb.Sheets("sheet1")
Set sht2 = wb.Sheets("sheet2")
Set sht3 = wb.Sheets("List of Changes")
lastrow1 = sht1.Cells(rows.Count, "C").End(xlUp).Row
lastrow2 = sht2.Cells(rows.Count, "C").End(xlUp).Row
k = 2
l = 3

sht3.Range("M1:T1") = Array("Seq", "Grade ID", "Item", "UOM", "Issue 1", "Issue 2", "Change", "Remark")
sht3.Range("M1:T1").Font.Bold = True

For j = 8 To 17
    For i = 2 To lastrow2
        For h = 2 To lastrow1
    Set rg = sht1.Range("E2:E" & lastrow1).Find(sht2.Range("E" & i))
            If rg Is Nothing Then
                If sht2.Cells(i, j) = 0 Then

                Else
                sht3.Range("N" & k).Value = sht2.Cells(i, 5).Value
                sht3.Range("O" & k).Value = sht2.Cells(1, j).Value
                M = sht3.Range("O" & k).Value
                sht3.Range("P" & k).Value = Right(M, 3)
                sht3.Range("O" & k).Value = Left(M, 10)
                sht3.Range("Q" & k).Value = 0
                sht3.Range("R" & k).Value = sht2.Cells(i, j).Value
                sht3.Range("S" & k).Value = sht2.Cells(i, j).Value - sht3.Range("Q" & k).Value
                k = k + 2
                End If

            ElseIf sht2.Cells(i, 5) <> sht1.Cells(h, 5) Then

            ElseIf sht2.Cells(i, 5) = sht1.Cells(h, 5) Then
                If sht2.Cells(i, j) = sht1.Cells(h, j) Then

                Else
                sht3.Range("N" & k).Value = sht2.Cells(i, 5).Value
                sht3.Range("O" & k).Value = sht2.Cells(1, j).Value
                M = sht3.Range("O" & k).Value
                sht3.Range("P" & k).Value = Right(M, 3)
                sht3.Range("O" & k).Value = Left(M, 10)
                sht3.Range("Q" & k).Value = sht1.Cells(h, j).Value
                sht3.Range("R" & k).Value = sht2.Cells(i, j).Value
                sht3.Range("S" & k).Value = sht2.Cells(i, j).Value - sht3.Range("Q" & k).Value
                k = k + 2
                End If

            End If
        Next h
    Next i
Next j

For j = 18 To 27
    For i = 2 To lastrow2
        For h = 2 To lastrow1
    Set rg = sht1.Range("E2:E" & lastrow1).Find(sht2.Range("E" & i))
            If rg Is Nothing Then
                If sht2.Cells(i, j) = 0 Then

                Else
                sht3.Range("N" & l).Value = sht2.Cells(i, 5).Value
                sht3.Range("O" & l).Value = sht2.Cells(1, j).Value
                M = sht3.Range("O" & l).Value
                sht3.Range("P" & l).Value = Right(M, 2)
                sht3.Range("O" & l).Value = Left(M, 10)
                sht3.Range("Q" & l).Value = 0
                sht3.Range("R" & l).Value = sht2.Cells(i, j).Value
                sht3.Range("S" & l).Value = sht2.Cells(i, j).Value - sht3.Range("Q" & l).Value
                l = l + 2
                End If

            ElseIf sht2.Cells(i, 5) <> sht1.Cells(h, 5) Then

            ElseIf sht2.Cells(i, 5) = sht1.Cells(h, 5) Then
                If sht2.Cells(i, j) = sht1.Cells(h, j) Then

                Else
                sht3.Range("N" & l).Value = sht2.Cells(i, 5).Value
                sht3.Range("O" & l).Value = sht2.Cells(1, j).Value
                M = sht3.Range("O" & l).Value
                sht3.Range("P" & l).Value = Right(M, 2)
                sht3.Range("O" & l).Value = Left(M, 10)
                sht3.Range("Q" & l).Value = sht1.Cells(h, j).Value
                sht3.Range("R" & l).Value = sht2.Cells(i, j).Value
                sht3.Range("S" & l).Value = sht2.Cells(i, j).Value - sht3.Range("Q" & l).Value
                l = l + 2
                End If
            End If

        Next h
    Next i
Next j

End Sub

Body:
posting my answer as below

Sub listofchanges()

   Dim wb As Workbook
   Dim ws1, ws2, ws3 As Worksheet
   Dim iLastRow1, iLastRow2, r1, r2, r3, c, x As Long
   Dim i, j As Integer
   Dim dict As Object, k, key, s As String
   Set dict = CreateObject("Scripting.Dictionary")

   ' prepare output sheet
   Set wb = ThisWorkbook
   Set ws3 = wb.Sheets("List of Changes")
   ws3.Cells.Clear
   With ws3.Range("M1:T1")
        .Value2 = Array("Seq", "Grade ID", "Item", "UOM", _
                        "Issue 1", "Issue 2", "Change", "Remark")
        .Font.Bold = True
   End With

   ' Scan sheet 1
   Set ws1 = wb.Sheets("iss1")
   iLastRow1 = ws1.Cells(rows.Count, "E").End(xlUp).Row

   ' build dictionary from sheet 1 key on column E
   For r1 = 2 To iLastRow1
       key = Trim(ws1.Cells(r1, "E"))
       If Len(key) > 0 Then
          If dict.exists(key) Then
              MsgBox "Duplicate key " & key, vbCritical, ws1.Name & " Row " & r1
              Exit Sub
          Else
              dict.Add key, r1
          End If
       End If
   Next

    ' Scan sheet 2, compare with sheet 1 and output to sheet 3
    Set ws2 = wb.Sheets("iss2")
    r3 = 2
    iLastRow2 = ws2.Cells(rows.Count, "E").End(xlUp).Row
    For i = 8 To 17
        If i = 13 Or i = 15 Or i = 16 Or i = 17 Then
        GoTo here1
        Else
        For r2 = 2 To iLastRow2
            key = Trim(ws2.Cells(r2, "E"))
            If Len(key) > 0 Then
                ' compare with iss2
                If dict.exists(key) Then
                    r1 = dict(key)
'                    If i = 17 Then dict.Remove key ' last loop and remove from dict
                Else
                    r1 = 0
                End If

                    s = ws2.Cells(1, i) ' column header
                    y = Len(s) - 7 'crop away unwanted words
                    With ws3
                        .Cells(r3, "N") = key
                        .Cells(r3, "O") = Left(s, y)
                        .Cells(r3, "P") = Right(s, 3)
                        If r1 = 0 Then
                            .Cells(r3, "Q") = 0
                        Else
                            .Cells(r3, "Q") = ws1.Cells(r1, i) ' this is wrong
                        End If
                        .Cells(r3, "R") = ws2.Cells(r2, i).Value2
                        .Cells(r3, "S").FormulaR1C1 = "=RC[-1] - RC[-2]" ' Q-R
                    End With
                    r3 = r3 + 2
           End If
        Next
        End If
here1:
    Next

    r3 = 3 'MT
    For i = 18 To 27
        If i = 23 Or i = 25 Or i = 26 Or i = 27 Then
        GoTo there1
        Else
        For r2 = 2 To iLastRow2
            key = Trim(ws2.Cells(r2, "E"))
            If Len(key) > 0 Then
                ' compare with iss2
                If dict.exists(key) Then
                    r1 = dict(key)
                    If i = 24 Then dict.Remove key ' last loop and remove from dict
                Else
                    r1 = 0
                End If

                    s = ws2.Cells(1, i) ' column header
                    y = Len(s) - 6 'crop away unwanted words
                    With ws3
                        .Cells(r3, "N") = key
                        .Cells(r3, "O") = Left(s, y)
                        .Cells(r3, "P") = Right(s, 2)
                        If r1 = 0 Then
                            .Cells(r3, "Q") = 0
                        Else
                            .Cells(r3, "Q") = ws1.Cells(r1, i) 'this is wrong
                        End If
                        .Cells(r3, "R") = ws2.Cells(r2, i).Value2
                        .Cells(r3, "S").FormulaR1C1 = "=RC[-1] - RC[-2]" ' Q-R
                    End With
                    r3 = r3 + 2
           End If
        Next
        End If
there1:
    Next
r4 = r3 - 2 + 1
r3 = r4

    ' add remaining keys from iss2 not in iss3
    For i = 8 To 17 'k15
        If i = 13 Or i = 15 Or i = 16 Or i = 17 Then
        GoTo here2
        Else
        For Each k In dict.keys
            r1 = dict(k)

                s = ws2.Cells(1, i) ' column header
                y = Len(s) - 7 'crop away unwanted words
                With ws3
                    .Cells(r3, "N") = CStr(k)
                    .Cells(r3, "O") = Left(s, y)
                    .Cells(r3, "P") = Right(s, 3)
                    If r1 = 0 Then
                        .Cells(r3, "Q") = 0
                    Else
                        .Cells(r3, "Q") = ws1.Cells(r1, i)
                    End If
'                    .Cells(r3, "R") = ws2.Cells(r1, i).Value2
'                    .Cells(r3, "Q") = ws1.Cells(r1, i)
                    .Cells(r3, "R") = 0    ' no sheet 2 value bcos not remove from dict, not in iss3
                    .Cells(r3, "S").FormulaR1C1 = "=RC[-1] - RC[-2]" ' Q-R

                End With
                r3 = r3 + 2
        Next
        End If
here2:
    Next

    r4 = r4 + 1
    r3 = r4
    For i = 18 To 27 'MT
        If i = 23 Or i = 25 Or i = 26 Or i = 27 Then
        GoTo there2
        Else
        For Each k In dict.keys
            r1 = dict(k)

                s = ws2.Cells(1, i) ' column header
                y = Len(s) - 6 'crop away unwanted words
                With ws3
                    .Cells(r3, "N") = CStr(k)
                    .Cells(r3, "O") = Left(s, y)
                    .Cells(r3, "P") = Right(s, 2)
                    If r1 = 0 Then
                        .Cells(r3, "Q") = 0
                    Else
                        .Cells(r3, "Q") = ws1.Cells(r1, i)
                    End If
'                    .Cells(r3, "R") = ws2.Cells(r1, i).Value2
'                    .Cells(r3, "Q") = ws1.Cells(r1, i)
                    .Cells(r3, "R") = 0    ' no sheet 2 value bcos not remove from dict, not in iss3
                    .Cells(r3, "S").FormulaR1C1 = "=RC[-1] - RC[-2]" ' Q-R

                End With
                r3 = r3 + 2
        Next
        End If
there2:
    Next

    MsgBox "OK", vbInformation
End Sub


来源: stackexchange

问:
Totally new kernel on OpenWRT
Is there any possibility to install totally new kernel on OpenWRT? Currently I have 3.18 version, but I have to downgrade to patched kernel by Candela Tech to install new firmware for ath10k. I have been searching in google how to bite this, but there is no fine instruction how to do that.

Update: (copied from answer of TS)

Nam Pham...

I tried to do as you instructed me, but there occured one problem

```<code>Applying patch platform/310-lib-add-rle-decompression.patch
patching file lib/Kconfig
Hunk #1 succeeded at 227 with fuzz 2 (offset -6 lines).
patching file lib/Makefile
Hunk #1 FAILED at 97.
1 out of 1 hunk FAILED -- rejects in file lib/Makefile
patching file include/linux/rle.h
patching file lib/rle.c
Patch platform/310-lib-add-rle-decompression.patch does not apply (enforce with -f)
make[3]: *** [sdk2/build_dir/target mips_34kc_uClibc-0.9.33.2/linux-ar71xx_generic/linux-3.17/.quilt_checked] Error 1
make[3]: Leaving directory `sdk2/target/linux/ar71xx'
make[2]: *** [compile] Error 2
make[2]: Leaving directory `sdk2/target/linux'
make[1]: *** [target/linux/compile] Error 2
make[1]: Leaving directory `sdk2'
make: *** [target/linux/compile] Error 2
</code>```

答:
in case someone finds this page for changing openwrt kernel, here is what I figured out based on this page info, thanks again!

Here I'm taking changing kernel 5.10 to kernel 5.16 for example for x86 platform:

update this file kernel info from 5.10.x -> 5.16.y:
target/linux/x86/Makefile

create this file: include/kernel-5.16
and its hash value is based on this calculating:
${openwrt_topdir}/staging_dir/host/bin/mkhash sha256 linux-5.10.92.tar.xz

create this file: target/linux/generic/config-5.16
if not sure, just #cp config-5.10 config-5.16

create confg-5.16 file under target/linux/x86/ this dir and subdirectory which have config-5.10

with these changes, I successfully build the 5.16 kernel in openwrt.

ContentLicense: CC BY-SA 3.0

Title: Totally new kernel on OpenWRT

Body:
Is there any possibility to install totally new kernel on OpenWRT? Currently I have 3.18 version, but I have to downgrade to patched kernel by Candela Tech to install new firmware for ath10k. I have been searching in google how to bite this, but there is no fine instruction how to do that.

Update: (copied from answer of TS)

Nam Pham...

I tried to do as you instructed me, but there occured one problem

Applying patch platform/310-lib-add-rle-decompression.patch
patching file lib/Kconfig
Hunk #1 succeeded at 227 with fuzz 2 (offset -6 lines).
patching file lib/Makefile
Hunk #1 FAILED at 97.
1 out of 1 hunk FAILED -- rejects in file lib/Makefile
patching file include/linux/rle.h
patching file lib/rle.c
Patch platform/310-lib-add-rle-decompression.patch does not apply (enforce with -f)
make[3]: *** [sdk2/build_dir/target mips_34kc_uClibc-0.9.33.2/linux-ar71xx_generic/linux-3.17/.quilt_checked] Error 1
make[3]: Leaving directory `sdk2/target/linux/ar71xx'
make[2]: *** [compile] Error 2
make[2]: Leaving directory `sdk2/target/linux'
make[1]: *** [target/linux/compile] Error 2
make[1]: Leaving directory `sdk2'
make: *** [target/linux/compile] Error 2

ContentLicense: CC BY-SA 4.0


问:
Check if string is reverse substring
I need to write function which will check if string s2 is reverse substring of string s1, and return 1 if the condition is true. Function should be made using pointer arithmetic.

For example:

```<code>char s1[] = "abcdef";
char s2[] = "edc";
</code>```

Function would return 1 because string s1 contains reverse string s2.

```<code>#include <stdio.h>
int reverseSubstring(const char *s1, const char *s2) {
  while (*s1 != '\0') {
    const char *p = s1;
    const char *q = s2;
    while (*p++ == *q++)
      if (*q == '\0')
        return 1;
    s1++;
  }
return 0;
}

int main() {
  char s1[] = "abcdef";
  char s2[] = "edc";
  printf("%d", reverseSubstring(s1, s2));
  return 0;
}
</code>```

This function does the opposite. It checks if the string is substring and in my case it returns 0. It should return 1. How to modify this to work?

Note: it is not allowed to use functions from the string.h, stdlib.h libraries, nor the sprintf and sscanf functions from the stdio.h library. It is not allowed to create auxiliary strings or strings in function or globally.

答:
Slight modification to parts of your code:

```<code>const char *q = s2;

while(*q) q++; // Make q point to end of string

while (*p++ == *--q) // Decrement instead of incrementing
  if (q == s2) // If we have traversed complete substring
    return 1;
</code>```

This is most likely good enough for a school task, which this most likely is. But it might be good to know that the operation q-- will invoke undefined behavior for an empty string because it will make q point to the element before the string. That can be easily fixed. Just add if(*s2 == '\0') return 1; in the beginning of the function because an empty string is a substring of every string.

For completeness, here is a full version with some small fixes and optimizations. I also took the liberty of replacing a while loop with the library function strlen even if it was forbidden in the task. After all, the while loop is described above, and strlen is easy to implement on your own.

```<code>const char *
reverseSubstring(const char *s1, const char *s2) {
    if(*s2 == '\0') return s1;

    const char *end = s2 + strlen(s2);

    while (*s1 != '\0') {
        const char *p = s1;
        const char *q = end;

        while (*p++ == *--q)) {
            if (q == s2) return s1;
        }

        s1++;
    }

    return NULL;
}
</code>```

Note that I changed the return type. It returns NULL if no match is found, but if a match is found, it returns a pointer to the first match. That means it contains more information for free.

Title: Check if string is reverse substring

Body:
I need to write function which will check if string s2 is reverse substring of string s1, and return 1 if the condition is true. Function should be made using pointer arithmetic.

For example:

char s1[] = "abcdef";
char s2[] = "edc";

Function would return 1 because string s1 contains reverse string s2.

#include <stdio.h>
int reverseSubstring(const char *s1, const char *s2) {
  while (*s1 != '\0') {
    const char *p = s1;
    const char *q = s2;
    while (*p++ == *q++)
      if (*q == '\0')
        return 1;
    s1++;
  }
return 0;
}

int main() {
  char s1[] = "abcdef";
  char s2[] = "edc";
  printf("%d", reverseSubstring(s1, s2));
  return 0;
}

This function does the opposite. It checks if the string is substring and in my case it returns 0. It should return 1. How to modify this to work?

Note: it is not allowed to use functions from the string.h, stdlib.h libraries, nor the sprintf and sscanf functions from the stdio.h library. It is not allowed to create auxiliary strings or strings in function or globally.

Body:
Slight modification to parts of your code:

const char *q = s2;

while(*q) q++; // Make q point to end of string

while (*p++ == *--q) // Decrement instead of incrementing
  if (q == s2) // If we have traversed complete substring
    return 1;

This is most likely good enough for a school task, which this most likely is. But it might be good to know that the operation q-- will invoke undefined behavior for an empty string because it will make q point to the element before the string. That can be easily fixed. Just add if(*s2 == '\0') return 1; in the beginning of the function because an empty string is a substring of every string.

For completeness, here is a full version with some small fixes and optimizations. I also took the liberty of replacing a while loop with the library function strlen even if it was forbidden in the task. After all, the while loop is described above, and strlen is easy to implement on your own.

const char *
reverseSubstring(const char *s1, const char *s2) {
    if(*s2 == '\0') return s1;

    const char *end = s2 + strlen(s2);

    while (*s1 != '\0') {
        const char *p = s1;
        const char *q = end;

        while (*p++ == *--q)) {
            if (q == s2) return s1;
        }

        s1++;
    }

    return NULL;
}

Note that I changed the return type. It returns NULL if no match is found, but if a match is found, it returns a pointer to the first match. That means it contains more information for free.


问:
Split a integer into its separate digits
Say I have an integer, 9802, is there a way I can split that value in the four individual digits : 9, 8, 0 & 2 ?</p>

答:
You probably want to use mod and divide to get these digits.

Something like:

```<code>Grab first digit:

   Parse digit: 9802 mod 10 = 2
   Remove digit: (int)(9802 / 10) = 980

Grab second digit:

   Parse digit: 980 mod 10 = 0
   Remove digit: (int)(980 / 10) = 98
</code>```

Something like that.

Body:
You probably want to use mod and divide to get these digits.

Something like:

Grab first digit:

   Parse digit: 9802 mod 10 = 2
   Remove digit: (int)(9802 / 10) = 980

Grab second digit:

   Parse digit: 980 mod 10 = 0
   Remove digit: (int)(980 / 10) = 98

Something like that.


问:
Checking for empty or null List<string>
I have a List where sometimes it is empty or null. I want to be able to check if it contains any List-item and if not then add an object to the List.</p>

```<code> // I have a list, sometimes it doesn't have any data added to it
    var myList = new List<object>();
 // Expression is always false
    if (myList == null)
        Console.WriteLine("List is never null");
    if (myList[0] == null)
        myList.Add("new item");
    //Errors encountered:  Index was out of range. Must be non-negative and less than the size of the collection.
    // Inner Exception says "null"
</code>```

答:
```<code>public static bool IsNullOrEmpty<T>(this IEnumerable<T> items)
{
   return !(items?.Any() ?? false);
}
</code>```

This extension method helps you determine if a list is either null or empty.
It can be used as follows:

```<code>using System;
using System.Linq;
using System.Collections.Generic;

public static class IEnumerableExtensions
{
    public static bool IsNullOrEmpty<T>(this IEnumerable<T> items)
    {
        return !(items?.Any() ?? false);
    }
}

public class Program
{
    public static void Main()
    {
        List<string> test1 = null;;
        Console.WriteLine($"List 1 is empty: {test1.IsNullOrEmpty()}");
        //Output: List 1 is empty: True

        var test2 = new System.Collections.Generic.List<string>();
        System.Console.WriteLine($"List 2 is empty: {test2.IsNullOrEmpty()}");
        //Output: List 2 is empty: True

        var test3 = new System.Collections.Generic.List<string>();
        test3.Add("test");
        System.Console.WriteLine($"List 3 is empty: {test3.IsNullOrEmpty()}");
        //Output: List 3 is empty: False
    }
}
</code>```

Title: Checking for empty or null List<string>

Body:
I have a List where sometimes it is empty or null. I want to be able to check if it contains any List-item and if not then add an object to the List.

 // I have a list, sometimes it doesn't have any data added to it
    var myList = new List<object>();
 // Expression is always false
    if (myList == null)
        Console.WriteLine("List is never null");
    if (myList[0] == null)
        myList.Add("new item");
    //Errors encountered:  Index was out of range. Must be non-negative and less than the size of the collection.
    // Inner Exception says "null"

Body:
public static bool IsNullOrEmpty<T>(this IEnumerable<T> items)
{
   return !(items?.Any() ?? false);
}

This extension method helps you determine if a list is either null or empty.
It can be used as follows:

using System;
using System.Linq;
using System.Collections.Generic;

public static class IEnumerableExtensions
{
    public static bool IsNullOrEmpty<T>(this IEnumerable<T> items)
    {
        return !(items?.Any() ?? false);
    }
}

public class Program
{
    public static void Main()
    {
        List<string> test1 = null;;
        Console.WriteLine($"List 1 is empty: {test1.IsNullOrEmpty()}");
        //Output: List 1 is empty: True

        var test2 = new System.Collections.Generic.List<string>();
        System.Console.WriteLine($"List 2 is empty: {test2.IsNullOrEmpty()}");
        //Output: List 2 is empty: True

        var test3 = new System.Collections.Generic.List<string>();
        test3.Add("test");
        System.Console.WriteLine($"List 3 is empty: {test3.IsNullOrEmpty()}");
        //Output: List 3 is empty: False
    }
}


问:
Simulating an if condition in the WHERE clause of an SQL query
I am trying to write a google BigQuery to select some records based on this condition:

```<code>if ID_parameter is not null:
   SELECT * WHERE ID=ID_parameter
else:
   SELECT * WHERE country_id=country_id_parameter and (name LIKE %name_parameter% OR name is null)
</code>```

The name_parameter should be optional but one of the ID_parameter or country_id_parameter must be provided.

Sorry, I am a newbie with SQL but I hope I stated what I want clearly.

答:
consider below approach</p>
```<code>select *
from your_table
where case
  when not id_parameter is null then id = id_parameter
  else country_id = country_id_parameter and (regexp_contains(name, name_parameter) or name is null)
end
</code>```

Body:
I am trying to write a google BigQuery to select some records based on this condition:

if ID_parameter is not null:
   SELECT * WHERE ID=ID_parameter
else:
   SELECT * WHERE country_id=country_id_parameter and (name LIKE %name_parameter% OR name is null)

The name_parameter should be optional but one of the ID_parameter or country_id_parameter must be provided.

Sorry, I am a newbie with SQL but I hope I stated what I want clearly.

Body:
consider below approach

select *
from your_table
where case
  when not id_parameter is null then id = id_parameter
  else country_id = country_id_parameter and (regexp_contains(name, name_parameter) or name is null)
end


问:
Binding in XAML ContentView does not update UI (ie Label) in Xamarin

Preamble

I have read many other questions here about this problem, but none solved my problem.

I also recently posted here about getting the property on the ContentView to be updated from the parent ContentPage. That is resolved, and I am certain the Property on the ContentView code behind is updating as intended.

The Problem

While using a custom ContentView MessageDisplayView, the elements in my XAML (ie: Label, WebView) do not update to match their bound properties in the code behind.

Situation

I have one BindableProperty Message of type MIME (email data object). This property is set when the ContentView is used on a ContentPage <view:MessageDisplayView x:Name="ReadingPane" Message="{Binding CurrentMessage}"/>. This works correctly.

In my ContentView MessageDisplayView, I have several Labels and one WebView. I have tried binding these elements to different things, but the UI is never updated.

I have tried:

Binding a label to a string property of Message, ie:

Binding a label to it's own property, ie:

Binding a label to a property that also has a BindableProperty accompanying it. (same code as above)

I have also made sure to try calling OnPropertyChanged(nameof(ToName));, as well as the one called for Message.

The only that will work, is if when OnPropertyChanged is called for Message, I manually update the Label text. But I don't want this. I would prefer if the code behind never dealt with the xaml/view.

I have verified that all the properties in the code behind are being updated correctly. The Intellisense works in xaml, allowing me to fill in the correct properties. Why does the UI never update to reflect the changes?

Code

The ConentView MessageDisplayView.xaml

<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:view="clr-Project.View"
             x:DataType="view:MessageDisplayView"
             x:Class="Project.View.MessageDisplayView">

  <ContentView.Content>
      <Grid>

            <StackLayout Orientation="Vertical"
                Grid.Column="0"
                Grid.Row="2"
                >
                <StackLayout Orientation="Horizontal">

                </StackLayout>
                <StackLayout Orientation="Horizontal">

                </StackLayout>
            </StackLayout>

            <WebView x:Name="BodyDisplay"
                Grid.Row="3"
                     BackgroundColor="AliceBlue"
                     Source="{Binding BodyHtmlViewSource}"
                />

        </Grid>
  </ContentView.Content>
</ContentView>
```
<p><em>The ConentView <code>MessageDisplayView.xaml.cs</code></em></p>
<pre class="lang-cs prettyprint-override"><code>using MimeKit;
using System.ComponentModel;
using Xamarin.Forms;

namespace Project.View
{
    public partial class MessageDisplayView : ContentView, INotifyPropertyChanged
    {
        public string FromName { get; set; }

        public string ToName
        {
            get
            {
                return (string)GetValue(ToNameProperty);
            }
            set
            {
                SetValue(ToNameProperty, value);
                OnPropertyChanged(nameof(ToName));
            }
        }

        public static BindableProperty ToNameProperty =
            BindableProperty.Create(nameof(ToName), typeof(string), typeof(MessageDisplayView), "Default To Field",
                BindingMode.TwoWay);

        public MimeMessage Message
        {
            get
            {
                return (MimeMessage)GetValue(MessageProperty);
            }
            set
            {
                SetValue(MessageProperty, value);
            }
        }

        public static BindableProperty MessageProperty =
            BindableProperty.Create(nameof(Message), typeof(MimeMessage), typeof(MessageDisplayView), new MimeMessage(),
                BindingMode.TwoWay);

        protected override void OnPropertyChanged(string propertyName = null)
        {
            base.OnPropertyChanged(propertyName);

            if (propertyName == MessageProperty.PropertyName)
            {
                if(Message != null)
                {
                    FromName = Message.From[0].ToString();
                    ToName = Message.To[0].Name;
                    OnPropertyChanged(nameof(ToName));
                    OnPropertyChanged(nameof(FromName));
                    //SubjectLine.Text = Message.Subject;    <--Manually setting does work (when uncommented)
                }
            }
        }

        public MessageDisplayView()
        {
            InitializeComponent();

            ToName = "This is a test name";   <-- I never see this
        }
    }
}
</code>```

UPDATE

The ContentPage MainPage.xaml

    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:c="Microsoft.Toolkit.Uwp.UI.Controls"
             xmlns:vm="clr-namespace:Project.ViewModel"
             xmlns:view="clr-namespace:Project.View"
             xmlns:fa="clr-namespace:FontAwesome"
             x:Class="Project.MainPage">
    <ContentPage.BindingContext>
        <vm:MainPageViewModel/>
    </ContentPage.BindingContext>

    <Grid x:Name="MainPageGrid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="300"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <view:MessageDisplayView x:Name="ReadingPane"
                Grid.Column="1"
                IsVisible="{Binding DisplayReadingPane}"
                Message="{Binding CurrentMessage}"
                />

    </Grid>

</ContentPage>
```
<ul>
<li>The ContentPage ViewModel <code>MainPageViewModel.cs</code></li>
</ul>
<pre class="lang-cs prettyprint-override"><code>namespace Project.ViewModel
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public class MainPageViewModel : ObservableObject
    {
        #region Variables

            private ObservableCollection<MimeMessage> currentBox;
            public ObservableCollection<MimeMessage> CurrentBox
            {
                get
                {
                    if (currentBox == null)
                        currentBox = new ObservableCollection<MimeMessage>();
                    return currentBox;
                }
            }

            private MimeMessage currentMessage;
            public MimeMessage CurrentMessage
            {
                get => currentMessage;
                set
                {
                    SetProperty(ref currentMessage, value, nameof(CurrentMessage));
                }
            }

        public static BindableProperty CurrentMessageProperty =
            BindableProperty.Create(nameof(CurrentMessage), typeof(MimeMessage), typeof(MainPageViewModel), new MimeMessage(), BindingMode.TwoWay);

    }
}
</code>```

MainPageViewModel base class ObservableObject*

namespace Xamarin.CommunityToolkit.ObjectModel
{

    public abstract class ObservableObject : INotifyPropertyChanged
    {
        private readonly DelegateWeakEventManager weakEventManager = new DelegateWeakEventManager();

        public event PropertyChangedEventHandler? PropertyChanged
        {
            add
            {
                weakEventManager.AddEventHandler(value, "PropertyChanged");
            }
            remove
            {
                weakEventManager.RemoveEventHandler(value, "PropertyChanged");
            }
        }
        protected virtual bool SetProperty<T>(ref T backingStore, T value, [CallerMemberName] string? propertyName = "", Action? onChanging = null, Action? onChanged = null, Func<T, T, bool>? validateValue = null)
        {
            if (EqualityComparer<T>.Default.Equals(backingStore, value))
            {
                return false;
            }

            if (validateValue != null && !validateValue!(backingStore, value))
            {
                return false;
            }

            onChanging?.Invoke();
            backingStore = value;
            onChanged?.Invoke();
            OnPropertyChanged(propertyName);
            return true;
        }

        protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = "")
        {
            weakEventManager.RaiseEvent(this, new PropertyChangedEventArgs(propertyName), "PropertyChanged");
        }
    }
}
```

答:
Hmm - i can't see where you set the message, but i changed your code a bit. I don't think you want all that inside the OnPropertyChanged method.. You could give it a try:</p>
```<code> public partial class MessageDisplayView : ContentView, INotifyPropertyChanged
{
    public string FromName { get; set; }

    public string ToName
    {
        get
        {
            return (string)GetValue(ToNameProperty);
        }
        set
        {
            SetValue(ToNameProperty, value);
            OnPropertyChanged(nameof(ToName));
        }
    }

    public static BindableProperty ToNameProperty =
        BindableProperty.Create(nameof(ToName), typeof(string), typeof(MessageDisplayView), "Default To Field",
            BindingMode.TwoWay);

    public MimeMessage Message
    {
        get
        {
            return (MimeMessage)GetValue(MessageProperty);
        }
        set
        {
            SetValue(MessageProperty, value);
            if (value is MimeMessage message)
            {
                FromName = message.From[0].ToString();
                ToName = message.To[0].Name;

                OnPropertyChanged(nameof(ToName));
                OnPropertyChanged(nameof(FromName));
            }

        }
    }

    public static BindableProperty MessageProperty =
        BindableProperty.Create(nameof(Message), typeof(MimeMessage), typeof(MessageDisplayView), new MimeMessage(),
            BindingMode.TwoWay);

    protected override void OnPropertyChanged(string propertyName = null)
    {
        base.OnPropertyChanged(propertyName);
    }

    public MessageDisplayView()
    {
        InitializeComponent();

        ToName = "This is a test name";  // < --I never see this
    }
}
</code>```

Body:
Preamble

I have read many other questions here about this problem, but none solved my problem.

I also recently posted here about getting the property on the ContentView to be updated from the parent ContentPage. That is resolved, and I am certain the Property on the ContentView code behind is updating as intended.

The Problem

While using a custom ContentView MessageDisplayView, the elements in my XAML (ie: Label, WebView) do not update to match their bound properties in the code behind.

Situation

I have one BindableProperty Message of type MIME (email data object). This property is set when the ContentView is used on a ContentPage <view:MessageDisplayView x:Name="ReadingPane" Message="{Binding CurrentMessage}"/>. This works correctly.

In my ContentView MessageDisplayView, I have several Labels and one WebView. I have tried binding these elements to different things, but the UI is never updated.

I have tried:

Binding a label to a string property of Message, ie:

Binding a label to it's own property, ie:

Binding a label to a property that also has a BindableProperty accompanying it. (same code as above)

I have also made sure to try calling OnPropertyChanged(nameof(ToName));, as well as the one called for Message.

The only that will work, is if when OnPropertyChanged is called for Message, I manually update the Label text. But I don't want this. I would prefer if the code behind never dealt with the xaml/view.

I have verified that all the properties in the code behind are being updated correctly. The Intellisense works in xaml, allowing me to fill in the correct properties. Why does the UI never update to reflect the changes?

Code

The ConentView MessageDisplayView.xaml

<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:view="clr-Project.View"
             x:DataType="view:MessageDisplayView"
             x:Class="Project.View.MessageDisplayView">

  <ContentView.Content>
      <Grid>

            <StackLayout Orientation="Vertical"
                Grid.Column="0"
                Grid.Row="2"
                >
                <StackLayout Orientation="Horizontal">

                </StackLayout>
                <StackLayout Orientation="Horizontal">

                </StackLayout>
            </StackLayout>

            <WebView x:Name="BodyDisplay"
                Grid.Row="3"
                     BackgroundColor="AliceBlue"
                     Source="{Binding BodyHtmlViewSource}"
                />

        </Grid>
  </ContentView.Content>
</ContentView>

The ConentView MessageDisplayView.xaml.cs

using MimeKit;
using System.ComponentModel;
using Xamarin.Forms;

namespace Project.View
{
    public partial class MessageDisplayView : ContentView, INotifyPropertyChanged
    {
        public string FromName { get; set; }

        public string ToName
        {
            get
            {
                return (string)GetValue(ToNameProperty);
            }
            set
            {
                SetValue(ToNameProperty, value);
                OnPropertyChanged(nameof(ToName));
            }
        }

        public static BindableProperty ToNameProperty =
            BindableProperty.Create(nameof(ToName), typeof(string), typeof(MessageDisplayView), "Default To Field",
                BindingMode.TwoWay);

        public MimeMessage Message
        {
            get
            {
                return (MimeMessage)GetValue(MessageProperty);
            }
            set
            {
                SetValue(MessageProperty, value);
            }
        }

        public static BindableProperty MessageProperty =
            BindableProperty.Create(nameof(Message), typeof(MimeMessage), typeof(MessageDisplayView), new MimeMessage(),
                BindingMode.TwoWay);

        protected override void OnPropertyChanged(string propertyName = null)
        {
            base.OnPropertyChanged(propertyName);

            if (propertyName == MessageProperty.PropertyName)
            {
                if(Message != null)
                {
                    FromName = Message.From[0].ToString();
                    ToName = Message.To[0].Name;
                    OnPropertyChanged(nameof(ToName));
                    OnPropertyChanged(nameof(FromName));
                    //SubjectLine.Text = Message.Subject;    <--Manually setting does work (when uncommented)
                }
            }
        }

        public MessageDisplayView()
        {
            InitializeComponent();

            ToName = "This is a test name";   <-- I never see this
        }
    }
}

UPDATE

The ContentPage MainPage.xaml

    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:c="Microsoft.Toolkit.Uwp.UI.Controls"
             xmlns:vm="clr-namespace:Project.ViewModel"
             xmlns:view="clr-namespace:Project.View"
             xmlns:fa="clr-namespace:FontAwesome"
             x:Class="Project.MainPage">
    <ContentPage.BindingContext>
        <vm:MainPageViewModel/>
    </ContentPage.BindingContext>

    <Grid x:Name="MainPageGrid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="300"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <view:MessageDisplayView x:Name="ReadingPane"
                Grid.Column="1"
                IsVisible="{Binding DisplayReadingPane}"
                Message="{Binding CurrentMessage}"
                />

    </Grid>

</ContentPage>

The ContentPage ViewModel MainPageViewModel.cs

namespace Project.ViewModel
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public class MainPageViewModel : ObservableObject
    {
        #region Variables

            private ObservableCollection<MimeMessage> currentBox;
            public ObservableCollection<MimeMessage> CurrentBox
            {
                get
                {
                    if (currentBox == null)
                        currentBox = new ObservableCollection<MimeMessage>();
                    return currentBox;
                }
            }

            private MimeMessage currentMessage;
            public MimeMessage CurrentMessage
            {
                get => currentMessage;
                set
                {
                    SetProperty(ref currentMessage, value, nameof(CurrentMessage));
                }
            }

        public static BindableProperty CurrentMessageProperty =
            BindableProperty.Create(nameof(CurrentMessage), typeof(MimeMessage), typeof(MainPageViewModel), new MimeMessage(), BindingMode.TwoWay);

    }
}

MainPageViewModel base class ObservableObject*

namespace Xamarin.CommunityToolkit.ObjectModel
{

    public abstract class ObservableObject : INotifyPropertyChanged
    {
        private readonly DelegateWeakEventManager weakEventManager = new DelegateWeakEventManager();

        public event PropertyChangedEventHandler? PropertyChanged
        {
            add
            {
                weakEventManager.AddEventHandler(value, "PropertyChanged");
            }
            remove
            {
                weakEventManager.RemoveEventHandler(value, "PropertyChanged");
            }
        }
        protected virtual bool SetProperty<T>(ref T backingStore, T value, [CallerMemberName] string? propertyName = "", Action? onChanging = null, Action? onChanged = null, Func<T, T, bool>? validateValue = null)
        {
            if (EqualityComparer<T>.Default.Equals(backingStore, value))
            {
                return false;
            }

            if (validateValue != null && !validateValue!(backingStore, value))
            {
                return false;
            }

            onChanging?.Invoke();
            backingStore = value;
            onChanged?.Invoke();
            OnPropertyChanged(propertyName);
            return true;
        }

        protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = "")
        {
            weakEventManager.RaiseEvent(this, new PropertyChangedEventArgs(propertyName), "PropertyChanged");
        }
    }
}

Body:
Hmm - i can't see where you set the message, but i changed your code a bit. I don't think you want all that inside the OnPropertyChanged method.. You could give it a try:

 public partial class MessageDisplayView : ContentView, INotifyPropertyChanged
{
    public string FromName { get; set; }

    public string ToName
    {
        get
        {
            return (string)GetValue(ToNameProperty);
        }
        set
        {
            SetValue(ToNameProperty, value);
            OnPropertyChanged(nameof(ToName));
        }
    }

    public static BindableProperty ToNameProperty =
        BindableProperty.Create(nameof(ToName), typeof(string), typeof(MessageDisplayView), "Default To Field",
            BindingMode.TwoWay);

    public MimeMessage Message
    {
        get
        {
            return (MimeMessage)GetValue(MessageProperty);
        }
        set
        {
            SetValue(MessageProperty, value);
            if (value is MimeMessage message)
            {
                FromName = message.From[0].ToString();
                ToName = message.To[0].Name;

                OnPropertyChanged(nameof(ToName));
                OnPropertyChanged(nameof(FromName));
            }

        }
    }

    public static BindableProperty MessageProperty =
        BindableProperty.Create(nameof(Message), typeof(MimeMessage), typeof(MessageDisplayView), new MimeMessage(),
            BindingMode.TwoWay);

    protected override void OnPropertyChanged(string propertyName = null)
    {
        base.OnPropertyChanged(propertyName);
    }

    public MessageDisplayView()
    {
        InitializeComponent();

        ToName = "This is a test name";  // < --I never see this
    }
}


问:
How to change text on mouse event in React
I'm trying to use the onMouseDown event in react to change the text but it doesn't work.
I saw a similar code which actually worked so I have no idea what could be wrong.

```<code>import React, { Component } from "react";

import "./ContentComponent.css";

class Content extends Component{
    constructor(){
        super()

        this.onClickForward = this.onClickForward.bind(this)
        this.onClickBack = this.onClickBack.bind(this)

        const img0 = require('./images/dog1.jpg');
        const img1 = require('./images/dog2.jpg');
        const img2 = require('./images/dog3.jpg');
        const img3 = require('./images/dog4.jpg');

        this.state={
            index: 0,
            imgList: [img0, img1, img2, img3]
        }

        this.state2 = {
            tekst: "Pies"
        }

    }
 onClickForward(){
            if (this.state.index + 1 === this.state.imgList.lenght) {
                this.setState({
                    index: 0
                })
            } else{
                this.setState({
                    index: this.state.index +1
                })
            }
        }

        onClickBack(){
            if (this.state.index - 1 === -1) {
                this.setState({
                    index: this.state.imgList.lenght -1
                })
            } else{
                this.setState({
                    index: this.state.index - 1
                })
            }
        }

        zmianaTekstu() {
            this.setState2({
                tekst: "Pies domowy - udomowiony gatunek ssaka drapieżnego z rodziny psowatych, traktowany przez niektóre ujęcia systematyczne za podgatunek wilka."
            })
        }

    render(){
        return(
            <div className="info">
                <img src={this.state.imgList[this.state.index]} alt="" className="mainImage" />
                <div className="btns">
                <button onClick={this.onClickBack}>Poprzednie</button>
                <button onClick={this.onClickForward}>Następne</button>
                </div>
                <div className="textInfo">
                    <h3 onMouseDown={() => this.zmianaTekstu()}>Click to change text</h3>
                    <p>{this.state2.tekst}</p>
                </div>
            </div>
        )
    }

}

export default Content;
</code>```

Console says

Uncaught TypeError: this.setState2 is not a function

The first state which changes images on button click actually works but I've pasted the whole code since maybe there is some interaction.

答:
You should use only one react's state in Class Component, in that way can access the setState and Update it. A state is an object so it can contain inside of it more variables, arrays, or even more objects. just hold inside the same state, variable for tekst

and update it like you update the first state, like so:

```<code> this.state = {
            index: 0,
            imgList: [img0, img1, img2, img3],
            tekst: 'pies',
        }
</code>```

And then update the state whenever you need, like so:

```<code> this.setState({
                tekst: "Pies domowy - udomowiony gatunek ssaka drapieżnego z rodziny psowatych, traktowany przez niektóre ujęcia systematyczne za podgatunek wilka."
            })
</code>```

Body:
I'm trying to use the onMouseDown event in react to change the text but it doesn't work.
I saw a similar code which actually worked so I have no idea what could be wrong.

import React, { Component } from "react";

import "./ContentComponent.css";

class Content extends Component{
    constructor(){
        super()

        this.onClickForward = this.onClickForward.bind(this)
        this.onClickBack = this.onClickBack.bind(this)

        const img0 = require('./images/dog1.jpg');
        const img1 = require('./images/dog2.jpg');
        const img2 = require('./images/dog3.jpg');
        const img3 = require('./images/dog4.jpg');

        this.state={
            index: 0,
            imgList: [img0, img1, img2, img3]
        }

        this.state2 = {
            tekst: "Pies"
        }

    }
 onClickForward(){
            if (this.state.index + 1 === this.state.imgList.lenght) {
                this.setState({
                    index: 0
                })
            } else{
                this.setState({
                    index: this.state.index +1
                })
            }
        }

        onClickBack(){
            if (this.state.index - 1 === -1) {
                this.setState({
                    index: this.state.imgList.lenght -1
                })
            } else{
                this.setState({
                    index: this.state.index - 1
                })
            }
        }

        zmianaTekstu() {
            this.setState2({
                tekst: "Pies domowy - udomowiony gatunek ssaka drapieżnego z rodziny psowatych, traktowany przez niektóre ujęcia systematyczne za podgatunek wilka."
            })
        }

    render(){
        return(

                <button onClick={this.onClickBack}>Poprzednie</button>
                <button onClick={this.onClickForward}>Następne</button>

 this.zmianaTekstu()}>Click to change text

{this.state2.tekst}

        )
    }

}

export default Content;

Console says

Uncaught TypeError: this.setState2 is not a function

The first state which changes images on button click actually works but I've pasted the whole code since maybe there is some interaction.

Body:
You should use only one react's state in Class Component, in that way can access the setState and Update it. A state is an object so it can contain inside of it more variables, arrays, or even more objects. just hold inside the same state, variable for tekst

and update it like you update the first state, like so:

 this.state = {
            index: 0,
            imgList: [img0, img1, img2, img3],
            tekst: 'pies',
        }

And then update the state whenever you need, like so:

 this.setState({
                tekst: "Pies domowy - udomowiony gatunek ssaka drapieżnego z rodziny psowatych, traktowany przez niektóre ujęcia systematyczne za podgatunek wilka."
            })


问:
BackHandler.removeEventListener is not wotking in react-native for android
Cannot get BackHandler.removeEventListener to work. Can anyone please guide as of how to use it?</p>

答:
import { useIsFocused } from '@react-navigation/native'

const isFocused = useIsFocused()

const myCallback = () => {

console.log("myCallback is running...")

}

```<code>useEffect(() => {

    if (isFocused) {
        BackHandler.addEventListener("hardwareBackPress", myCallback)
    }

    return () => {
        BackHandler.removeEventListener("hardwareBackPress", myCallback)
    }

}, [isFocused])
</code>```

Body:
import { useIsFocused } from '@react-navigation/native'

const isFocused = useIsFocused()

const myCallback = () => {

console.log("myCallback is running...")

}

useEffect(() => {

    if (isFocused) {
        BackHandler.addEventListener("hardwareBackPress", myCallback)
    }

    return () => {
        BackHandler.removeEventListener("hardwareBackPress", myCallback)
    }

}, [isFocused])


问:
How do i turn this string into 2 arrays in python?
I have this string and want to turn it into two arrays, one has the film title and the other one has the year. Their positions in the array need to correspond with each other. Is there a way to do this?</p>
```<code>films = ("""Endless Love (1981), Top Gun (1986), The Color of Money (1986), Rain Man (1988),
Born on the Fourth of July (1989), Interview with the Vampire: The Vampire Chronicles (1994),
Mission: Impossible (1996), Jerry Maguire (1996), The Matrix (1999), Mission: Impossible II (2000),
Vanilla Sky (2001), Cocktail (1988), A Few Good Men (1992), The Firm (1993), Eyes Wide Shut (1999),
Magnolia (1999), Minority Report (2002), Austin Powers in Goldmember (2002), Days of Thunder (1990),
The Powers of Matthew Star (1982), Cold Mountain (2003), The Talented Mr. Ripley (1999),
 War of the Worlds (2005), The Oprah Winfrey Show (1986), Far and Away (1992), Taps (1981),
 The Last Samurai (2003), Valkyrie (2008), Jack Reacher (2012), Edge of Tomorrow (2014),
 Enemy of the State (1998), Mission: Impossible III (2006), Crimson Tide (1995), Reign Over Me (2007),
 Batman Forever (1995), Batman Begins (2005), The Simpsons (1989), The Simpsons: Brother from the Same Planet (1993),
 The Simpsons: When You Dish Upon a Star (1998), End of Days (1999), House of D (2004), The Indian Runner (1991),
  Harry & Son (1984), Mission: Impossible - Ghost Protocol (2011), Aladdin (1992), Pacific Rim (2013),
  Oblivion (2013), Knight and Day (2010),
""")
</code>```

答:
You shuold clear all "new line" (|n) and use try/except to pass over the last elemet issue.</p>
```<code>films = ("""Endless Love (1981), Top Gun (1986), The Color of Money (1986), Rain Man (1988),
Born on the Fourth of July (1989), Interview with the Vampire: The Vampire Chronicles (1994),
Mission: Impossible (1996), Jerry Maguire (1996), The Matrix (1999), Mission: Impossible II (2000),
Vanilla Sky (2001), Cocktail (1988), A Few Good Men (1992), The Firm (1993), Eyes Wide Shut (1999),
Magnolia (1999), Minority Report (2002), Austin Powers in Goldmember (2002), Days of Thunder (1990),
The Powers of Matthew Star (1982), Cold Mountain (2003), The Talented Mr. Ripley (1999),
 War of the Worlds (2005), The Oprah Winfrey Show (1986), Far and Away (1992), Taps (1981),
 The Last Samurai (2003), Valkyrie (2008), Jack Reacher (2012), Edge of Tomorrow (2014),
 Enemy of the State (1998), Mission: Impossible III (2006), Crimson Tide (1995), Reign Over Me (2007),
 Batman Forever (1995), Batman Begins (2005), The Simpsons (1989), The Simpsons: Brother from the Same Planet (1993),
 The Simpsons: When You Dish Upon a Star (1998), End of Days (1999), House of D (2004), The Indian Runner (1991),
  Harry & Son (1984), Mission: Impossible - Ghost Protocol (2011), Aladdin (1992), Pacific Rim (2013),
  Oblivion (2013), Knight and Day (2010),
""")

movies = []
years = []
for item in films.replace("\n", "").split("),"):
      try:
        movies.append(item.split(" (")[0])
        years.append(item.split(" (")[-1])
      except:
        ...
</code>```

Body:
I have this string and want to turn it into two arrays, one has the film title and the other one has the year. Their positions in the array need to correspond with each other. Is there a way to do this?

films = ("""Endless Love (1981), Top Gun (1986), The Color of Money (1986), Rain Man (1988),
Born on the Fourth of July (1989), Interview with the Vampire: The Vampire Chronicles (1994),
Mission: Impossible (1996), Jerry Maguire (1996), The Matrix (1999), Mission: Impossible II (2000),
Vanilla Sky (2001), Cocktail (1988), A Few Good Men (1992), The Firm (1993), Eyes Wide Shut (1999),
Magnolia (1999), Minority Report (2002), Austin Powers in Goldmember (2002), Days of Thunder (1990),
The Powers of Matthew Star (1982), Cold Mountain (2003), The Talented Mr. Ripley (1999),
 War of the Worlds (2005), The Oprah Winfrey Show (1986), Far and Away (1992), Taps (1981),
 The Last Samurai (2003), Valkyrie (2008), Jack Reacher (2012), Edge of Tomorrow (2014),
 Enemy of the State (1998), Mission: Impossible III (2006), Crimson Tide (1995), Reign Over Me (2007),
 Batman Forever (1995), Batman Begins (2005), The Simpsons (1989), The Simpsons: Brother from the Same Planet (1993),
 The Simpsons: When You Dish Upon a Star (1998), End of Days (1999), House of D (2004), The Indian Runner (1991),
  Harry & Son (1984), Mission: Impossible - Ghost Protocol (2011), Aladdin (1992), Pacific Rim (2013),
  Oblivion (2013), Knight and Day (2010),
""")

Body:
You shuold clear all "new line" (|n) and use try/except to pass over the last elemet issue.

films = ("""Endless Love (1981), Top Gun (1986), The Color of Money (1986), Rain Man (1988),
Born on the Fourth of July (1989), Interview with the Vampire: The Vampire Chronicles (1994),
Mission: Impossible (1996), Jerry Maguire (1996), The Matrix (1999), Mission: Impossible II (2000),
Vanilla Sky (2001), Cocktail (1988), A Few Good Men (1992), The Firm (1993), Eyes Wide Shut (1999),
Magnolia (1999), Minority Report (2002), Austin Powers in Goldmember (2002), Days of Thunder (1990),
The Powers of Matthew Star (1982), Cold Mountain (2003), The Talented Mr. Ripley (1999),
 War of the Worlds (2005), The Oprah Winfrey Show (1986), Far and Away (1992), Taps (1981),
 The Last Samurai (2003), Valkyrie (2008), Jack Reacher (2012), Edge of Tomorrow (2014),
 Enemy of the State (1998), Mission: Impossible III (2006), Crimson Tide (1995), Reign Over Me (2007),
 Batman Forever (1995), Batman Begins (2005), The Simpsons (1989), The Simpsons: Brother from the Same Planet (1993),
 The Simpsons: When You Dish Upon a Star (1998), End of Days (1999), House of D (2004), The Indian Runner (1991),
  Harry & Son (1984), Mission: Impossible - Ghost Protocol (2011), Aladdin (1992), Pacific Rim (2013),
  Oblivion (2013), Knight and Day (2010),
""")

movies = []
years = []
for item in films.replace("\n", "").split("),"):
      try:
        movies.append(item.split(" (")[0])
        years.append(item.split(" (")[-1])
      except:
        ...


问:
Can I pass different parameter instead of (n1,n2,n3)?
Write a function called sumArray which accepts a single argument: an array of numbers. It should return the sum of all the numbers in the array.

Condition:

You will need a variable to keep track of total. It should start out as zero.

Loop over the array for each element, add it to total variable.

function sumArray(n1, n2, n3) {
  let total = n1 + n2 + n3;
  return total;
}

sumArray([3,45,66]);```

答:
Just loop from array and get the output

function sumArray(arr){
  let total = 0;
  arr.forEach((i) => total+=i);
  return total;
}
console.log(sumArray([3,45,66]));```
</div>
</div>
</p>
<p>Or you can try with reduce as explained by Cristian</p>
<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>function sumArray(arr){
  const reducer = (previousValue, currentValue) => previousValue + currentValue;
  let total = arr.reduce(reducer)
  return total;
}
console.log(sumArray([3,45,66]));</code>```

Body:
Just loop from array and get the output

function sumArray(arr){
  let total = 0;
  arr.forEach((i) => total+=i);
  return total;
}
console.log(sumArray([3,45,66]));

Or you can try with reduce as explained by Cristian

function sumArray(arr){
  const reducer = (previousValue, currentValue) => previousValue + currentValue;
  let total = arr.reduce(reducer)
  return total;
}
console.log(sumArray([3,45,66]));


问:
Chrome on Linux: can't play <audio> and WebRTC audio at the same time
With Chrome under Linux we can't use both WebRTC audio (video call) and the <audio> tag in a single web page, meaning that only one of the two works at a time:

During a single browser session, when a <audio> tag is played (which can be heared), a WebRTC video call (ie. MediaStream) doesn't play any sound (microphone and video works, though).

Likewise, when the WebRTC video call is started first, it works perfectly (audio playback is okay) but then no <audio> tag works anymore.

Obviously there seems to be some sort of conflict, although the problem is not related to WebRTC video call and <audio> running at the same time - it also happens when one starts after the other having been stopped already.

Under Windows the same web application works without any problems, happily playing both sound sources, meaning that is related to Chrome under Linux.

Is this a known limitation of Chrome under Linux? Is there any workaround?

technical details

Chrome 48 32bit

Debian Jessie Linux 32bit

Intel Celeron J1900 with 4GB ram (a thin client)

ALSA 1.0.28 playback with playback over HDMI

Video calling implemented using SimpleWebRTC.

aplay -l output:

```<code>**** List of PLAYBACK Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALC662 rev1 Analog [ALC662 rev1 Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 3: HDMI 0 [HDMI 0]
  Subdevices: 0/1
  Subdevice #0: subdevice #0
</code>```

Code that starts <audio> playback:

```<code>addAudio(audio) {

  this.ringAudio = new Audio();
  this.ringSource = document.createElement("source");
  this.ringSource.type = "audio/mpeg";
  this.ringSource.src = audio;
  this.ringAudio.appendChild(this.ringSource);
  this.ringAudio.play();

}
</code>```

答:
I've been struggling with this issue for long time. Aks many people in linux commmunity and try many code in my Terminal. Until I got this trick.

It's seem simple, but works for me. No need write: sudo...

Just open Terminal and write:

alxamixer

It's not about your browser, just need a bit configuration in system.

Body:
With Chrome under Linux we can't use both WebRTC audio (video call) and the <audio> tag in a single web page, meaning that only one of the two works at a time:

During a single browser session, when a <audio> tag is played (which can be heared), a WebRTC video call (ie. MediaStream) doesn't play any sound (microphone and video works, though).

Likewise, when the WebRTC video call is started first, it works perfectly (audio playback is okay) but then no <audio> tag works anymore.

Obviously there seems to be some sort of conflict, although the problem is not related to WebRTC video call and <audio> running at the same time - it also happens when one starts after the other having been stopped already.

Under Windows the same web application works without any problems, happily playing both sound sources, meaning that is related to Chrome under Linux.

Is this a known limitation of Chrome under Linux? Is there any workaround?

technical details

Chrome 48 32bit

Debian Jessie Linux 32bit

Intel Celeron J1900 with 4GB ram (a thin client)

ALSA 1.0.28 playback with playback over HDMI

Video calling implemented using SimpleWebRTC.

aplay -l output:

**** List of PLAYBACK Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALC662 rev1 Analog [ALC662 rev1 Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 3: HDMI 0 [HDMI 0]
  Subdevices: 0/1
  Subdevice #0: subdevice #0

Code that starts <audio> playback:

addAudio(audio) {

  this.ringAudio = new Audio();
  this.ringSource = document.createElement("source");
  this.ringSource.type = "audio/mpeg";
  this.ringSource.src = audio;
  this.ringAudio.appendChild(this.ringSource);
  this.ringAudio.play();

}


问:
Tailwind CSS: How to use custom percentages in padding?
How can we use custom percentage on padding in Tailwind CSS?

My config:

```<code>theme: {
    extend: {
      spacing: {
        '80\%': '80%', // p-80% - doesn't work
      }
    },
  },
</code>```

We can achieve that in the old way with the plain CSS:

```<code>.p-80\% {
   padding: 80%;
}
</code>```

But ideally, we can do it with Tailwind too.

Any ideas?

答:
While the other answers do provide an answer, this can be frustrating if you only need to use the custom value once. I found this answer when trying to solve such an issue, so for those who find this after me, tailwind now supports arbitrary values.

You can use them by appending square brackets containing a CSS value (e.g. [80%]) to a prefix such as p- for padding or mr- for margin-right.

    Hello world!

```

Body:
How can we use custom percentage on padding in Tailwind CSS?

My config:

theme: {
    extend: {
      spacing: {
        '80\%': '80%', // p-80% - doesn't work
      }
    },
  },

We can achieve that in the old way with the plain CSS:

.p-80\% {
   padding: 80%;
}

But ideally, we can do it with Tailwind too.

Any ideas?

Body:
While the other answers do provide an answer, this can be frustrating if you only need to use the custom value once. I found this answer when trying to solve such an issue, so for those who find this after me, tailwind now supports arbitrary values.

You can use them by appending square brackets containing a CSS value (e.g. [80%]) to a prefix such as p- for padding or mr- for margin-right.

<div class="p-[80%]">
    Hello world!
</div>


答:
Keep doing modulo-10 and divide-by-10:

```<code>int n; // from somewhere
while (n) { digit = n % 10; n /= 10; }
</code>```

This spits out the digits from least-significant to most-significant. You can clearly generalise this to any number base.

Title: Split a integer into its separate digits

Body: Say I have an integer, 9802, is there a way I can split that value in the four individual digits : 9, 8, 0 & 2 ?

Body:
Keep doing modulo-10 and divide-by-10:

int n; // from somewhere
while (n) { digit = n % 10; n /= 10; }

This spits out the digits from least-significant to most-significant. You can clearly generalise this to any number base.


问:
Add key value pair to all objects in array
I wanted to add a key:value parameter to all the objects in an array.

eg:

```<code>var arrOfObj = [{name: 'eve'},{name:'john'},{name:'jane'}];
</code>```

Now I wanted to add a new parameter, isActive to all the objects so the resulting array will look like.

eg:

```<code>    [{
    name: 'eve',
    isActive: true
}, {
    name: 'john',
    isActive: true
}, {
    name: 'jane',
    isActive: true
}]
</code>```

I can always loop through the array and insert a key,value pair. But was wondering if there was a better way to do so

答:
var arrOfObj = [{name: 'eve'},{name:'john'},{name:'jane'}];
const result = arrOfObj.map((name) => {
    name["isActive"] = true;
    return name;
});
console.log(result);```

Body:
I wanted to add a key:value parameter to all the objects in an array.

eg:

var arrOfObj = [{name: 'eve'},{name:'john'},{name:'jane'}];

Now I wanted to add a new parameter, isActive to all the objects so the resulting array will look like.

eg:

    [{
    name: 'eve',
    isActive: true
}, {
    name: 'john',
    isActive: true
}, {
    name: 'jane',
    isActive: true
}]

I can always loop through the array and insert a key,value pair. But was wondering if there was a better way to do so


问:
How to suppress PyExcel Empty Row Warning during file read to SQLAlclemy model
I am saving the contents of an excel file to a SQLAlchemy DB table using pyexcel as following: pyexcel.save_as(file_name='my_excel_file.xlsx',
    name_columns_by_row=0,
                 dest_session=db.session,
                 dest_table=models.MyModel)

This is working well and saving the data but it's leaving several log messages that One empty row is found in the terminal. How do I suppress these messages to avoid polluting the logs? I know about the empty rows and they have no impact to the data loading

答:
So turns out pyexcel does a bit more on abstractions, the heavy lifting is done by pyexcel-io which does the basic input and output.
With this understanding, in the pyexcel docs there is a parameter skip_empty_rows=True for when you reading from a source file which if you pass to the pyexcel.save_as function and this silences the logged messages, so it was exactly what I needed in this use-case.
See PyExcel Docs Ref for pyexcel.save_as


问:
Add + 1 every multiple of 10 in C#
I'm making an endless runner game with Unity and in this game for every 10 coins I collect, it increases the level by 1 with a maximum of 10. Currently, I'm doing this:

```<code>IF(coins >= 10 and coins < 20) level = 2
IF(coins >= 20 and coins <= 30) level = 3
</code>```

and so on till level 10.

But I'm sure that this code is badly written, I'm thinking in use the for statement but I'm a newbie to C#, any ideas?

答:
use mod operation with 10

if(coins%10 == 0)
{
    level = coins / 10;
}
else
{
    level = (coins / 10) + 1;
}

// then check if level is bigger than 10
if(level > 10)
{
    level = 10;
}
```

Title: Add + 1 every multiple of 10 in C#

Body:
I'm making an endless runner game with Unity and in this game for every 10 coins I collect, it increases the level by 1 with a maximum of 10. Currently, I'm doing this:

IF(coins >= 10 and coins < 20) level = 2
IF(coins >= 20 and coins <= 30) level = 3

and so on till level 10.

But I'm sure that this code is badly written, I'm thinking in use the for statement but I'm a newbie to C#, any ideas?


问:
Perl: HTTP::Tiny delete leaves broken anchor tags
I wrote a script that collects all URLs within a buffer that's read from a database, checks whether that page still exists, and uses HTTP::Tiny to delete the URL from the buffer if it is unreachable or returns invalid.

The problem is that HTTP::Tiny delete left anchor tags like text here that are invalid. The links are highlighted, but there's obviously no way to click them. Is this a deficiency with HTTP::Tiny delete or am I using it wrong?

```<code>my $html_full = $ref->{'fulltext'}; # $ref is a pointer to the database
my $dom_buff = Mojo::DOM->new($html_buff);
foreach my $ele ($dom_buff->find('a[href]')->each) {
  my $url = $ele->attr('href');
  my $response = HTTP::Tiny->new(default_headers => { Accept => '*/*' })->get($url);
  if ($response->{success}) {
     $success_fulltext_urls{$ref->{'id'}}{$url} = 1;
  } else {
     delete $ele->attr->{href};
     $html_buff = $dom_buff;
     $html_buff =~ s{<a>(.*?)</a>}{$1}sg;
     my $sql      = "not described here";
     write_sql($dbh,$sql,$ref->{'id'});
  }
}
</code>```

Here is an example string, after it's been processed by the code above.

```<code>This week, perhaps the most interesting articles include "<a>Finding \r\n  that Windows is superior to Linux is biased</a>," "<a href=\"http://www.example.com/content/view/118693\">How \r\n  to set up DNS for Linux VPNs</a>," and "<a href=\"http://www.example.com/content/view/118664 \">Writing \r\n  an Incident Handling and Recovery Plan</a>."
</code>```

Note the string "Finding \r\n  that Windows is superior to Linux is biased" used to be a valid link with an href, but the delete function stripped all that out and left the anchor tags.

Is this the intended effect? Perhaps I should be using a different library or function within HTTP::Tiny?

答:
You're misunderstanding what delete does. All your code does is remove the href attribute from that DOM element in your Mojo::DOM representation. It has nothing to do with HTTP::Tiny.

What you actually want to do is call ->strip on the  element, which removes it from the DOM, but keeps its content intact.

Since you are already using Mojo::DOM, you can just as well use Mojo::UserAgent. There is no need to pull in another UA module. You've already got the whole Mojolicious installed anyway.

You can use a HEAD request rather than a GET request to check if a resource is available. There is no need to download the whole thing, the headers are sufficient.

Your code (without the DB part) can be reduced to this.

use strict;
use warnings;
use Mojo::DOM;
use Mojo::UserAgent;

my $ua = Mojo::UserAgent->new;
my $dom = Mojo::DOM->new(<DATA>);

foreach my $element ($dom->find('a[href]')->each) {
    $element->strip
        unless $ua->head($element->attr('href'))->res->is_success;
}

print $dom;

__DATA__
This link works.
This one does not!
```
<p>This outputs:</p>
```This link works. This one does not!
```

Body:
I wrote a script that collects all URLs within a buffer that's read from a database, checks whether that page still exists, and uses HTTP::Tiny to delete the URL from the buffer if it is unreachable or returns invalid.

The problem is that HTTP::Tiny delete left anchor tags like text here that are invalid. The links are highlighted, but there's obviously no way to click them. Is this a deficiency with HTTP::Tiny delete or am I using it wrong?

my $html_full = $ref->{'fulltext'}; # $ref is a pointer to the database
my $dom_buff = Mojo::DOM->new($html_buff);
foreach my $ele ($dom_buff->find('a[href]')->each) {
  my $url = $ele->attr('href');
  my $response = HTTP::Tiny->new(default_headers => { Accept => '*/*' })->get($url);
  if ($response->{success}) {
     $success_fulltext_urls{$ref->{'id'}}{$url} = 1;
  } else {
     delete $ele->attr->{href};
     $html_buff = $dom_buff;
     $html_buff =~ s{(.*?)}{$1}sg;
     my $sql      = "not described here";
     write_sql($dbh,$sql,$ref->{'id'});
  }
}

Here is an example string, after it's been processed by the code above.

This week, perhaps the most interesting articles include "Finding \r\n  that Windows is superior to Linux is biased," "How \r\n  to set up DNS for Linux VPNs," and "Writing \r\n  an Incident Handling and Recovery Plan."

Note the string "Finding \r\n  that Windows is superior to Linux is biased" used to be a valid link with an href, but the delete function stripped all that out and left the anchor tags.

Is this the intended effect? Perhaps I should be using a different library or function within HTTP::Tiny?

Body:
You're misunderstanding what delete does. All your code does is remove the href attribute from that DOM element in your Mojo::DOM representation. It has nothing to do with HTTP::Tiny.

What you actually want to do is call ->strip on the <a> element, which removes it from the DOM, but keeps its content intact.

Since you are already using Mojo::DOM, you can just as well use Mojo::UserAgent. There is no need to pull in another UA module. You've already got the whole Mojolicious installed anyway.

You can use a HEAD request rather than a GET request to check if a resource is available. There is no need to download the whole thing, the headers are sufficient.

Your code (without the DB part) can be reduced to this.

use strict;
use warnings;
use Mojo::DOM;
use Mojo::UserAgent;

my $ua = Mojo::UserAgent->new;
my $dom = Mojo::DOM->new(<DATA>);

foreach my $element ($dom->find('a[href]')->each) {
    $element->strip
        unless $ua->head($element->attr('href'))->res->is_success;
}

print $dom;

__DATA__
This <a href="http://example.org">link works</a>.
This <a href="http://httpstat.us/404">one does not</a>!

This outputs:

This <a href="http://example.org">link works</a>. This one does not!


问:
How to make a shared library not link to its deps in gn
I am using gn as make system, and I have a shared libS which deps libA and libB, but I want to functions in libA are not linked into libS ( it will be linked into main ) while functions libB are linked into libS.

My problem is:

If I use deps or public deps for libA, the include path will be added ( it is what I want) but all functions will also be linked too ( it is not what I want)

If I use data_deps, the functions will not be linked (I want), but the include path will not be added too ( not I want )

答:
If you only want libS to have libA's include paths, you can use a config.

//path/to/libA/BUILD.gn:

```<code>config("config") {
  include_dirs = [ "include" ]
}

static_library("libA") {
  public_configs = [ ":config" ]
  sources = [ ... ]
  # etc
}
</code>```

//path/to/libS/BUILD.gn:

```<code>shared_library("libS") {
  configs = [ "//path/to/libA:config" ]
  deps = [ "//path/to/libB" ]
}
</code>```

This way GN will add -Ipath/to/libA to the compile lines for the sources in libS, but not add anything from libA to the link line.

Body:
If you only want libS to have libA's include paths, you can use a config.

//path/to/libA/BUILD.gn:

config("config") {
  include_dirs = [ "include" ]
}

static_library("libA") {
  public_configs = [ ":config" ]
  sources = [ ... ]
  # etc
}

//path/to/libS/BUILD.gn:

shared_library("libS") {
  configs = [ "//path/to/libA:config" ]
  deps = [ "//path/to/libB" ]
}

This way GN will add -Ipath/to/libA to the compile lines for the sources in libS, but not add anything from libA to the link line.


问:
How to access vue instance in Vuex
I declare a global variable in the main.js of the Vue.js project.

```<code>Vue.prototype.$API = "myapihere"
</code>```

And I want to use this from everywhere.
and it's work properly by using this.$API.

But in Vuex it does not work.

```<code>console.log(this.$API);
</code>```

Here this.$API is undefined.

How I use my $API in Vuex.

答:
As of recently, under Vuex 4.* and Vue 3.*, this.$app hasn't been defined for the store object. Instead you have Vue Router defined as this.$router.

So for javascript, the way to get app in store would be like so:

The code would now be: router.app = app; and inside, say, an action: let app = this.$router.app;

Title: How to access vue instance in Vuex

Body:
I declare a global variable in the main.js of the Vue.js project.

Vue.prototype.$API = "myapihere"

And I want to use this from everywhere.
and it's work properly by using this.$API.

But in Vuex it does not work.

console.log(this.$API);

Here this.$API is undefined.

How I use my $API in Vuex.