So I'm doing a Minesweeper game for a class and everything is going fine more or less, however I had encountered a problem. Sometimes the Mines are being places in the same cell. I.e.: If i have 10 bombs sometimes 9 bombs would be displayed.
Here is my Code so far:
Sub Minesweeper()
Dim Mines As Integer
Dim i As Integer
Dim j As Integer
Dim n As Integer
Dim m As Integer
Dim OverLap As Integer
'This is for Centering Text
For i = 8 To 15
For j = 6 To 13
Cells(i, j).HorizontalAlignment = xlCenter
Next j
Next i
'This is for setting Table/Board
For i = 8 To 15
For j = 6 To 13
'By default all cells will = 1 until bomb is placed
Cells(i, j).Value = 1
Next j
Next i
'This generates certain Number of Mines
For Mines = 1 To 10
Cells(((Int((15 - 8 + 1) * Rnd + 1)) + 7), ((Int((13 - 6 + 1) * Rnd + 1))) + 5).Value = 0
Next Mines
'This is for converting Mines to o and color change
For i = 8 To 15
For j = 6 To 13
If Cells(i, j).Value = 0 Then
Cells(i, j).Value = "o"
Cells(i, j).Font.Color = RGB(250, 0, 0)
ElseIf Cells(i, j).Value >= 1 Then
Cells(i, j).Font.Color = RGB(0, 0, 0)
End If
Next j
Next i
End Sub
Do an 'If' check of values during for Mines = 1 to 10. Declare your cell values first then check if that cell is a 1. If it is then place the 0. If it isn't then generate another random cell and recheck.
For Mines = 1 To 10
1
x = Int((15 - 8 + 1) * Rnd + 1) + 7
y = Int((13 - 6 + 1) * Rnd + 1) + 5
If Cells(x, y).Value = 1 Then
Cells(x, y).Value = 0
Else:
GoTo 1
End If
Next Mines
Related
Sub WriteToZeroBasedArray()
Dim E As Integer
Dim rCount As Long: rCount = Worksheets("0618").Cells.SpecialCells(xlLastCell).Row
For E = 9 To 11
Dim V() As Variant ' Note the parentheses!
Dim P() As Variant
Dim N() As Variant
Dim Index As Long
Dim Index_2 As Long
Dim Index_3 As Long
Dim cCount As Long: cCount = Worksheets("0618").Cells.SpecialCells(xlLastCell).Column ' e.g.
Dim c As Long '배열에 값 저장하기
For c = 7 To cCount
If 0 < Worksheets("0618").Cells(E, c).Value And Worksheets("0618").Cells(E, c).Value < 100 Then
ReDim Preserve V(Index)
' A safer way (Option Base related):
'ReDim Preserve V(0 To Index)
V(Index) = Worksheets("0618").Cells(2, c).Value
Index = Index + 1
ReDim Preserve P(Index_2)
P(Index_2) = Worksheets("0618").Cells(4, c).Value
Index_2 = Index_2 + 1
ReDim Preserve N(Index_3)
N(Index_3) = Worksheets("0618").Cells(E, c).Value
Index_3 = Index_3 + 1
End If
Next c
Dim K As Integer
Dim L As Integer
K = UBound(V) '배열의 값 차례로 Sheet2에 넣기
For L = 0 To K
If L < 5 Then
Worksheets("sheet2").Cells(L + 6 + 14 * (E - 9), 1).Value = V(L)
Worksheets("sheet2").Cells(L + 6 + 14 * (E - 9), 2).Value = P(L)
Worksheets("sheet2").Cells(L + 6 + 14 * (E - 9), 3).Value = N(L)
Else
Worksheets("sheet2").Cells(L + 1 + 14 * (E - 9), 5).Value = V(L)
Worksheets("sheet2").Cells(L + 1 + 14 * (E - 9), 6).Value = P(L)
Worksheets("sheet2").Cells(L + 1 + 14 * (E - 9), 7).Value = N(L)
End If
Next
Dim FP As Integer
Dim Sum As Integer
Sum = 0
'수량*단가 구하기
For FP = (6 + 14 * (E - 9)) To (10 + 14 * (E - 9))
Worksheets("sheet2").Cells(FP, 4).Value = Worksheets("sheet2").Cells(FP, 2).Value * Worksheets("sheet2").Cells(FP, 3).Value
Worksheets("sheet2").Cells(FP, 8).Value = Worksheets("sheet2").Cells(FP, 6).Value * Worksheets("sheet2").Cells(FP, 7).Value
'총액 구하기
Sum = Sum + Worksheets("sheet2").Cells(FP, 4).Value + Worksheets("sheet2").Cells(FP, 8).Value
'0 지우기
If Worksheets("sheet2").Cells(FP, 4).Value = 0 Then
Worksheets("sheet2").Cells(FP, 4).ClearContents
End If
If Worksheets("sheet2").Cells(FP, 8).Value = 0 Then
Worksheets("sheet2").Cells(FP, 8).ClearContents
End If
Next
'총액 구하기2
Worksheets("sheet2").Cells(12 + 14 * (E - 9), 8).Value = Sum
'받으실 분
Worksheets("sheet2").Cells(3 + 14 * (E - 9), 2).Value = Worksheets("0618").Cells(E, 3).Value
'주소
Worksheets("sheet2").Cells(3 + 14 * (E - 9), 5).Value = Worksheets("0618").Cells(E, 2).Value
'서식 복사'
Worksheets("sheet3").Range("A1:H13").Copy
Worksheets("sheet2").Range("A" & 15 + 14 * (E - 9)).PasteSpecial
If Index = 0 Then Exit Sub
Next
Debug.Print Join(V, vbLf)
End Sub
I expected this code to be like this
But the result is like this
When E = 9, the code runs exactly the same as I thought, but when E is over 10, it doesn't.
when E = 9, the V array's values and orders are like this [grape, apple], and that's what I wanted.
However, when E = 10, I want the V array's value to be like this [orange]
but the result says it is [ , , orange]
Could someone tell me what's wrong with my code?
For me, the two (different) pictures look like 'Chinese'... So, I cannot refer to them.
No need to use Index, Index2 and Index3. Use only Index and increment it at the second loop end;
'replace this line
Index_3 = Index_3 + 1
'with
Index = Index + 1
' and comment all the previous index incrementations
You must reinitialize the used arrays content and used Index at the first loop end:
'your code...
If Index = 0 Then Exit Sub 'after this existing code line
Erase V: Erase P: Erase N: Index = 0
Next
'Your code
Now, using Redim Preserve to often is bad from memory handling point of view. Please, try firstly ReDim to a value to exceed the necessary number of necessary elements (ReDim V(cCount)) and use only of the end: Redim Preserve V(Index -1). Do the same for the other two used arrays...
I´ve an Excel file with 10 Columns. In columns 2, 3, 4 I have a number or a dash.
If the sum of these 3 cells is greater than 1, I need to replace that entire row with n rows that have only one of the columns with the value 1 but the other cells stay the same.
Example
1 - - #-> leave it as is
- 2 - #-> replace that row with 2 rows : - 1 - ; - 1 -
2 - 1 #-> replace that row with 3 rows : 1 - - ; 1 - - ; - - 1;
I managed to iterate from bottom up, but I´m having trouble storing a row in memory, manipulate it and insert below.
Sub Test()
Dim rng As Range
Dim count20, count40, count45, total, i As Integer
Set rng = Range("A3", Range("A3").End(xlDown))
For i = rng.Cells.count To 1 Step -1
count20 = 0
count40 = 0
count45 = 0
total = 0
count20 = Cells(rng.Item(i).Row, 10).Value
If count20 > 1 Then
total = total + count20
End If
count40 = Cells(rng.Item(i).Row, 11).Value
If count40 > 1 Then
total = total + count40
End If
count45 = Cells(rng.Item(i).Row, 12).Value
If count45 > 1 Then
total = total + count45
End If
If total <> 0 Then
MsgBox total
End If
Next i
End Sub
EDIT 2
I’ve provided alternative code based on your latest comment. It uses columns J-L (10-12) as the numeric cells to be changed, and columns A-I (1-9) and M-AD (13-30) as the cells with text to be preserved. As before, sheet 1 starting in row 3 is assumed, and you can change this to whatever you need.
Option Explicit
Sub testJtoL()
Dim LastRow As Long, i As Long, j As Long, c As Long, _
insertR As Long, TopRow As Long, BottomRow As Long
Dim b As Range
Dim ws As Worksheet
'*** This code is based your values being in Columns J-L (10-12) in sheet 1 ***
'Set sheet 1 as ws
Set ws = Sheet1
'Sheet1 column J is used here to get your last row
LastRow = ws.Cells(Rows.Count, 10).End(xlUp).Row
'*** This code is based your values starting in Row 3 ***
For c = LastRow To 3 Step -1
'Determine number of rows to insert based on sum of that row
insertR = Application.WorksheetFunction.Sum(Range(Cells(c, 10), Cells(c, 12))) - 1
If insertR = 0 Then GoTo skip
'STEP 1 insert the correct number of rows
With ws.Range(Cells(c + 1, 1), Cells(c + insertR, 30))
.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
End With
'STEP 2 fill the values into the correct number of rows
insertR = insertR + 1
With ws.Range(Cells(c, 1), Cells(c, 30))
.Resize(insertR, 30).Value = .Value
End With
TopRow = c
If insertR = 0 And c = 3 Then
BottomRow = c
Else
BottomRow = c + insertR - 1
End If
'STEP 3 replace all numbers with 1 or "-"
'Replace numbers in column J
If ws.Range(Cells(c, 10), Cells(c, 10)).Value = "-" Then GoTo SkipA
i = ws.Range(Cells(c, 10), Cells(c, 10)).Value
j = 1
For Each b In ws.Range(Cells(TopRow, 10), Cells(BottomRow, 10))
If j <= i Then
b.Value = 1
b.Offset(0, 1).Value = "-"
b.Offset(0, 2).Value = "-"
Else
b.Value = "-"
End If
j = j + 1
Next b
SkipA:
'Replace numbers in column K
j = 1
For Each b In ws.Range(Cells(TopRow, 11), Cells(BottomRow, 11))
If b.Value = "-" Then GoTo SkipB
i = b.Value
If j <= i Then
b.Value = 1
b.Offset(0, 1).Value = "-"
Else
b.Value = "-"
End If
j = j + 1
SkipB:
Next b
'Replace numbers in column L
j = 1
For Each b In ws.Range(Cells(TopRow, 12), Cells(BottomRow, 12))
If b.Value = "-" Then GoTo SkipC
i = b.Value
If j <= i Then
b.Value = 1
Else
b.Value = "-"
End If
j = j + 1
SkipC:
Next b
skip:
Next c
End Sub
I'm looking into a do while loop to enter a number on cellcert, 4, and return a value on cellcert,5. However, if the cellcert, 4 value is more than 1, it will add 5 for every "1's" so it has the If logic below:
1 = 18, 2 = 18+5, 3 = 18+5+5, 4 = 18+5+5+5 and so on...
This is why I'm looking into incorporating separate function(s) to do the adding of 5 code and call it within Sub TATcomputation()
Sub TATcomputation()
Dim certcell As Integer
certcell = 2
Do While Cells(certcell, 4).Value <> ""
Cells(certcell, 5).Value = Cells(certcell, 4).Value * 18
certcell = certcell + 1
Loop
End Sub
You dont need a IF statement here. Just always start with 18 and then multiply your cell value in Column D (less one) by 5
'Do While....
Cells(certvalue, 5).Value = 18 + ((Cells(certvalue, 4) -1) *5)
'certvalue = cervalue + 1
'Loop
You should qualify those Cells objects or use a With block btw
How about:
Sub TATcomputation()
Dim certcell As Integer
certcell = 2
Do While Cells(certcell, 4).Value <> ""
If certcell = 2 Then
Cells(certcell, 5).Value = Cells(certcell, 4).Value * 18
Else
Cells(certcell, 5).Value = Cells(certcell, 4).Value * (18 + (5 * (certcell - 2)))
End If
certcell = certcell + 1
Loop
End Sub
I have this problem to be sorted out. Namely, I need the code that will place the same values in the range until corresponding cells value increases by one. Once it does the value needs to be incremented by 0.2 and place incremented number until again the corresponding cell value is higher by one
Sub Button4_Click()
range1 = Sheets(3).Range("g2").End(xlDown).Row
range2 = "g2:g" & range1
For i = 2 To range1
If Cells(i, 7).Value <= 360 Then
Cells(i, 8) = 60
range3_n = Cells(i, 8).Row
End If
Next
j = 0.2
k = 1
For i = range3_n To range1
If Cells(i, 7) > 360 And Cells(i, 7) <= (360 + k) And Cells(i, 7) <= (360 +
100) Then
Cells(i, 8) = 60 + (k * j)
k = k + 1
End If
Next
MsgBox ("END")
End Sub
Based on the comments, and keeping the code structure the exact same as it is, an easy solution is adding a new IF Statement after your last one:
IF (Cells(i, 7) - Int(Cells(i, 7)) = 0) Then
The code should look like:
Sub Button4_Click()
range1 = Sheets(1).Range("g2").End(xlDown).Row
range2 = "g2:g" & range1
For i = 2 To range1
If Cells(i, 7).Value <= 360 Then
Cells(i, 8) = 60
range3_n = Cells(i, 8).Row
End If
Next
range3_n = range3_n + 1 'start at cell 361 instead
j = 0.2
k = 1
For i = range3_n To range1
If Cells(i, 7) > 360 And Cells(i, 7) <= (361 + k) And Cells(i, 7) <= (360 + 100) Then
If Int(Cells(i - 1, 7)) - Int(Cells(i, 7)) <> 0 Then
Cells(i, 8) = 60 + (k * j)
k = k + 1
Else
Cells(i, 8) = Cells(i - 1, 8)
End If
End If
Next i
MsgBox ("END")
End Sub
What this does is, it takes the value of the cell, subtracts the integer version of that value (360.1 = 360, 365.4 = 365, etc.) and ensures that equals zero. Any decimal value > .0 will fail, and will not meet the criteria.
Example:
360.0 - 360 = 0 PASS
360.1 - 360 = .1 FAIL
360.4 - 360 = .4 FAIL
360.7 - 360 = .7 FAIL
361.0 - 361 = 0 PASS
Try it out and let me know.
thanks in advance for taking the time to help. I have built a Do While loop in VBA that for some reason breaks when j = 1. I have in cells C3:C7 these values: 13,14,14,13,14.
Here's the short script:
Dim i, j, n As Integer
Dim List(0) As Integer
i = o
j = 0
n = 0
Do While Cells(i + 3, 3) <> ""
If Cells(i + 3, 3) > 13 Then
List(j) = i + 3
j = j + 1
Cells(i + 3, 4) = "Noted"
i = i + 1
ElseIf Cells(i + 3, 3) = 13 Then
Cells(i + 3, 4) = "Skipped"
i = i + 1
Else
i = i + 1
End If
Loop
For n = j To n = 0
Rows(List(n)).Delete
Next
Thanks again!
Your intent is sound, but there are quite a few errors. See commented code below for details
Sub Demo()
' ~~ must explicitly type each variable. Use Long
Dim i As Long, j As Long, n As Long
Dim List() As Long '<~~ dynamic array
i = 3 '<~~ eliminate the klunky +3
j = 0
n = 0
ReDim List(0 To 0) '<~~ initialise dynamic array
Do While Cells(i, 3) <> vbNullString
If Cells(i, 3) > 13 Then
ReDim Preserve List(0 To j) '<~~ resize array
List(j) = i
j = j + 1
Cells(i, 4) = "Noted"
ElseIf Cells(i, 3) = 13 Then
Cells(i, 4) = "Skipped"
End If
i = i + 1 '<~~ simplify, its called in each if case anyway
Loop
' j will end up 1 greater than size of array
If j > 0 Then '<~~ only execute if we found some rows to delete
For n = j - 1 To 0 Step -1 '<~~ For loop syntax
Rows(List(n)).Delete
Next
End If
End Sub